From 38e9ff44165568ed2f90404bbaa423a694cabb52 Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Wed, 26 Aug 2020 16:10:21 -0400 Subject: [PATCH 001/116] update version to 0.8.0-dev --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index db77a366406..5467c506032 100644 --- a/version.go +++ b/version.go @@ -4,7 +4,7 @@ package ipfs var CurrentCommit string // CurrentVersionNumber is the current application's version literal -const CurrentVersionNumber = "0.7.0-dev" +const CurrentVersionNumber = "0.8.0-dev" const ApiVersion = "/go-ipfs/" + CurrentVersionNumber + "/" From 0ad6a92716423dc23d944bce1fec2ad18f163907 Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Wed, 26 Aug 2020 20:51:53 -0400 Subject: [PATCH 002/116] docs: update config to indicate SECIO deprecation --- docs/config.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/config.md b/docs/config.md index 8670bd9d384..274280b0404 100644 --- a/docs/config.md +++ b/docs/config.md @@ -1255,7 +1255,7 @@ receiver supports. When establishing an _inbound_ connection, go-ipfs will let the initiator choose the protocol, but will refuse to use any of the disabled transports. -Supported transports are: TLS (priority 100), SECIO (priority 200), Noise +Supported transports are: TLS (priority 100), SECIO (Disabled: i.e. priority false), Noise (priority 300). No default priority will ever be less than 100. @@ -1272,12 +1272,12 @@ Type: `priority` #### `Swarm.Transports.Security.SECIO` -[SECIO](https://github.com/libp2p/specs/tree/master/secio) is the most widely +[SECIO](https://github.com/libp2p/specs/tree/master/secio) was the most widely supported IPFS & libp2p security transport. However, it is currently being phased out in favor of more popular and better vetted protocols like TLS and Noise. -Default: `200` +Default: `false` Type: `priority` From ba1d2252125826939d33c3d254d67ff18c46918b Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Sun, 30 Aug 2020 02:16:15 -0400 Subject: [PATCH 003/116] fix: ipfs dht put/get commands now work on keys encoded as peerIDs and fail early for namespaces other than /pk or /ipns --- core/commands/dht.go | 24 +++++++++--------------- go.mod | 1 - 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/core/commands/dht.go b/core/commands/dht.go index aeaa7712b80..07136a72379 100644 --- a/core/commands/dht.go +++ b/core/commands/dht.go @@ -18,7 +18,6 @@ import ( path "github.com/ipfs/go-path" peer "github.com/libp2p/go-libp2p-core/peer" routing "github.com/libp2p/go-libp2p-core/routing" - b58 "github.com/mr-tron/base58/base58" ) var ErrNotDHT = errors.New("routing service is not a DHT") @@ -676,20 +675,15 @@ func printEvent(obj *routing.QueryEvent, out io.Writer, verbose bool, override p func escapeDhtKey(s string) (string, error) { parts := path.SplitList(s) - switch len(parts) { - case 1: - k, err := b58.Decode(s) - if err != nil { - return "", err - } - return string(k), nil - case 3: - k, err := b58.Decode(parts[2]) - if err != nil { - return "", err - } - return path.Join(append(parts[:2], string(k))), nil - default: + if len(parts) != 3 || + parts[0] != "" || + !(parts[1] == "ipns" || parts[1] == "pk") { return "", errors.New("invalid key") } + + k, err := peer.Decode(parts[2]) + if err != nil { + return "", err + } + return path.Join(append(parts[:2], string(k))), nil } diff --git a/go.mod b/go.mod index 3b754d5e96f..964da0bae23 100644 --- a/go.mod +++ b/go.mod @@ -88,7 +88,6 @@ require ( github.com/lucas-clemente/quic-go v0.18.0 github.com/mattn/go-runewidth v0.0.9 // indirect github.com/mitchellh/go-homedir v1.1.0 - github.com/mr-tron/base58 v1.2.0 github.com/multiformats/go-multiaddr v0.3.1 github.com/multiformats/go-multiaddr-dns v0.2.0 github.com/multiformats/go-multibase v0.0.3 From 78586509c6ae510f986f5f225873f8b59bd1ba8a Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Tue, 8 Sep 2020 13:43:13 -0400 Subject: [PATCH 004/116] chore: bump js-ipfs in interop CI to 0.50.1 --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index b1724121b4d..6eca3087362 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -174,7 +174,7 @@ jobs: name: Installing dependencies command: | npm init -y - npm install ipfs@^0.49.1-rc.2 + npm install ipfs@^0.50.1 npm install ipfs-interop@^2.0.1 npm install mocha-circleci-reporter@0.0.3 working_directory: ~/ipfs/go-ipfs/interop From 0a394211388265284f11f4e8f3ea4c41a8c883a3 Mon Sep 17 00:00:00 2001 From: Jacob Heun Date: Wed, 9 Sep 2020 13:03:30 +0200 Subject: [PATCH 005/116] chore: bump ipfs-interop ci version --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 6eca3087362..4fe87124e89 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -175,7 +175,7 @@ jobs: command: | npm init -y npm install ipfs@^0.50.1 - npm install ipfs-interop@^2.0.1 + npm install ipfs-interop@^3.0.0 npm install mocha-circleci-reporter@0.0.3 working_directory: ~/ipfs/go-ipfs/interop - run: From 6cbda0f62fbd2481b0ae2e0d0ce518576992ad1e Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Tue, 8 Sep 2020 13:08:53 -0400 Subject: [PATCH 006/116] refactor: put all --ipns-base options in one place --- core/commands/keyencode/keyencode.go | 5 ++++- core/commands/keystore.go | 20 ++++++++++---------- core/commands/name/ipnsps.go | 4 ++-- core/commands/name/publish.go | 4 ++-- 4 files changed, 18 insertions(+), 15 deletions(-) diff --git a/core/commands/keyencode/keyencode.go b/core/commands/keyencode/keyencode.go index 015a6844eff..3ba55f86c10 100644 --- a/core/commands/keyencode/keyencode.go +++ b/core/commands/keyencode/keyencode.go @@ -1,11 +1,14 @@ package keyencode import ( + cmds "github.com/ipfs/go-ipfs-cmds" peer "github.com/libp2p/go-libp2p-core/peer" mbase "github.com/multiformats/go-multibase" ) -const IPNSKeyFormatOptionName = "ipns-base" +const ipnsKeyFormatOptionName = "ipns-base" + +var OptionIPNSBase = cmds.StringOption(ipnsKeyFormatOptionName, "", "Encoding used for keys: Can either be a multibase encoded CID or a base58btc encoded multihash. Takes {b58mh|base36|k|base32|b...}.").WithDefault("base36") type KeyEncoder struct { baseEnc *mbase.Encoder diff --git a/core/commands/keystore.go b/core/commands/keystore.go index 844d7709635..0e242ee96a4 100644 --- a/core/commands/keystore.go +++ b/core/commands/keystore.go @@ -81,7 +81,7 @@ var keyGenCmd = &cmds.Command{ Options: []cmds.Option{ cmds.StringOption(keyStoreTypeOptionName, "t", "type of the key to create: rsa, ed25519").WithDefault(keyStoreAlgorithmDefault), cmds.IntOption(keyStoreSizeOptionName, "s", "size of the key to generate"), - cmds.StringOption(ke.IPNSKeyFormatOptionName, "", "Encoding used for keys: Can either be a multibase encoded CID or a base58btc encoded multihash. Takes {b58mh|base36|k|base32|b...}.").WithDefault("base36"), + ke.OptionIPNSBase, }, Arguments: []cmds.Argument{ cmds.StringArg("name", true, false, "name of key to create"), @@ -108,7 +108,7 @@ var keyGenCmd = &cmds.Command{ if sizefound { opts = append(opts, options.Key.Size(size)) } - keyEnc, err := ke.KeyEncoderFromString(req.Options[ke.IPNSKeyFormatOptionName].(string)) + keyEnc, err := ke.KeyEncoderFromString(req.Options[ke.OptionIPNSBase.Name()].(string)) if err != nil { return err } @@ -223,7 +223,7 @@ var keyImportCmd = &cmds.Command{ Tagline: "Import a key and prints imported key id", }, Options: []cmds.Option{ - cmds.StringOption(ke.IPNSKeyFormatOptionName, "", "Encoding used for keys: Can either be a multibase encoded CID or a base58btc encoded multihash. Takes {b58mh|base36|k|base32|b...}.").WithDefault("base36"), + ke.OptionIPNSBase, }, Arguments: []cmds.Argument{ cmds.StringArg("name", true, false, "name to associate with key in keychain"), @@ -236,7 +236,7 @@ var keyImportCmd = &cmds.Command{ return fmt.Errorf("cannot import key with name 'self'") } - keyEnc, err := ke.KeyEncoderFromString(req.Options[ke.IPNSKeyFormatOptionName].(string)) + keyEnc, err := ke.KeyEncoderFromString(req.Options[ke.OptionIPNSBase.Name()].(string)) if err != nil { return err } @@ -303,10 +303,10 @@ var keyListCmd = &cmds.Command{ }, Options: []cmds.Option{ cmds.BoolOption("l", "Show extra information about keys."), - cmds.StringOption(ke.IPNSKeyFormatOptionName, "", "Encoding used for keys: Can either be a multibase encoded CID or a base58btc encoded multihash. Takes {b58mh|base36|k|base32|b...}.").WithDefault("base36"), + ke.OptionIPNSBase, }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - keyEnc, err := ke.KeyEncoderFromString(req.Options[ke.IPNSKeyFormatOptionName].(string)) + keyEnc, err := ke.KeyEncoderFromString(req.Options[ke.OptionIPNSBase.Name()].(string)) if err != nil { return err } @@ -352,14 +352,14 @@ var keyRenameCmd = &cmds.Command{ }, Options: []cmds.Option{ cmds.BoolOption(keyStoreForceOptionName, "f", "Allow to overwrite an existing key."), - cmds.StringOption(ke.IPNSKeyFormatOptionName, "", "Encoding used for keys: Can either be a multibase encoded CID or a base58btc encoded multihash. Takes {b58mh|base36|k|base32|b...}.").WithDefault("base36"), + ke.OptionIPNSBase, }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { api, err := cmdenv.GetApi(env, req) if err != nil { return err } - keyEnc, err := ke.KeyEncoderFromString(req.Options[ke.IPNSKeyFormatOptionName].(string)) + keyEnc, err := ke.KeyEncoderFromString(req.Options[ke.OptionIPNSBase.Name()].(string)) if err != nil { return err } @@ -402,14 +402,14 @@ var keyRmCmd = &cmds.Command{ }, Options: []cmds.Option{ cmds.BoolOption("l", "Show extra information about keys."), - cmds.StringOption(ke.IPNSKeyFormatOptionName, "", "Encoding used for keys: Can either be a multibase encoded CID or a base58btc encoded multihash. Takes {b58mh|base36|k|base32|b...}.").WithDefault("base36"), + ke.OptionIPNSBase, }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { api, err := cmdenv.GetApi(env, req) if err != nil { return err } - keyEnc, err := ke.KeyEncoderFromString(req.Options[ke.IPNSKeyFormatOptionName].(string)) + keyEnc, err := ke.KeyEncoderFromString(req.Options[ke.OptionIPNSBase.Name()].(string)) if err != nil { return err } diff --git a/core/commands/name/ipnsps.go b/core/commands/name/ipnsps.go index 07e050bf65d..0aa7c459a4e 100644 --- a/core/commands/name/ipnsps.go +++ b/core/commands/name/ipnsps.go @@ -74,10 +74,10 @@ var ipnspsSubsCmd = &cmds.Command{ Tagline: "Show current name subscriptions", }, Options: []cmds.Option{ - cmds.StringOption(ke.IPNSKeyFormatOptionName, "", "Encoding used for keys: Can either be a multibase encoded CID or a base58btc encoded multihash. Takes {b58mh|base36|k|base32|b...}.").WithDefault("base36"), + ke.OptionIPNSBase, }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - keyEnc, err := ke.KeyEncoderFromString(req.Options[ke.IPNSKeyFormatOptionName].(string)) + keyEnc, err := ke.KeyEncoderFromString(req.Options[ke.OptionIPNSBase.Name()].(string)) if err != nil { return err } diff --git a/core/commands/name/publish.go b/core/commands/name/publish.go index 3e1edf82c30..99f0ab3cd2b 100644 --- a/core/commands/name/publish.go +++ b/core/commands/name/publish.go @@ -83,14 +83,14 @@ Alternatively, publish an using a valid PeerID (as listed by cmds.StringOption(ttlOptionName, "Time duration this record should be cached for. Uses the same syntax as the lifetime option. (caution: experimental)"), cmds.StringOption(keyOptionName, "k", "Name of the key to be used or a valid PeerID, as listed by 'ipfs key list -l'.").WithDefault("self"), cmds.BoolOption(quieterOptionName, "Q", "Write only final hash."), - cmds.StringOption(ke.IPNSKeyFormatOptionName, "", "Encoding used for keys: Can either be a multibase encoded CID or a base58btc encoded multihash. Takes {b58mh|base36|k|base32|b...}.").WithDefault("base36"), + ke.OptionIPNSBase, }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { api, err := cmdenv.GetApi(env, req) if err != nil { return err } - keyEnc, err := ke.KeyEncoderFromString(req.Options[ke.IPNSKeyFormatOptionName].(string)) + keyEnc, err := ke.KeyEncoderFromString(req.Options[ke.OptionIPNSBase.Name()].(string)) if err != nil { return err } From 904ad1626a09f7fdec788f8f9513ad866889721a Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Tue, 8 Sep 2020 13:10:02 -0400 Subject: [PATCH 007/116] fix: remove the (empty) alias for --ipns-base --- core/commands/keyencode/keyencode.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/commands/keyencode/keyencode.go b/core/commands/keyencode/keyencode.go index 3ba55f86c10..1db095d6d83 100644 --- a/core/commands/keyencode/keyencode.go +++ b/core/commands/keyencode/keyencode.go @@ -8,7 +8,7 @@ import ( const ipnsKeyFormatOptionName = "ipns-base" -var OptionIPNSBase = cmds.StringOption(ipnsKeyFormatOptionName, "", "Encoding used for keys: Can either be a multibase encoded CID or a base58btc encoded multihash. Takes {b58mh|base36|k|base32|b...}.").WithDefault("base36") +var OptionIPNSBase = cmds.StringOption(ipnsKeyFormatOptionName, "Encoding used for keys: Can either be a multibase encoded CID or a base58btc encoded multihash. Takes {b58mh|base36|k|base32|b...}.").WithDefault("base36") type KeyEncoder struct { baseEnc *mbase.Encoder From 491b88a6eb30387d99d18304c1894ab90c4fdaba Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Wed, 9 Sep 2020 13:20:26 -0400 Subject: [PATCH 008/116] chore: bump go-ipfs-cmds --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 964da0bae23..c22d959dada 100644 --- a/go.mod +++ b/go.mod @@ -31,7 +31,7 @@ require ( github.com/ipfs/go-graphsync v0.1.1 github.com/ipfs/go-ipfs-blockstore v0.1.4 github.com/ipfs/go-ipfs-chunker v0.0.5 - github.com/ipfs/go-ipfs-cmds v0.3.0 + github.com/ipfs/go-ipfs-cmds v0.4.0 github.com/ipfs/go-ipfs-config v0.9.0 github.com/ipfs/go-ipfs-ds-help v0.1.1 github.com/ipfs/go-ipfs-exchange-interface v0.0.1 diff --git a/go.sum b/go.sum index 8651aca83fc..b615e827333 100644 --- a/go.sum +++ b/go.sum @@ -352,8 +352,8 @@ github.com/ipfs/go-ipfs-chunker v0.0.1 h1:cHUUxKFQ99pozdahi+uSC/3Y6HeRpi9oTeUHbE 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.3.0 h1:mi9oYrSCox5aBhutqAYqw6/9crlyGbw4E/aJtwS4zI4= -github.com/ipfs/go-ipfs-cmds v0.3.0/go.mod h1:ZgYiWVnCk43ChwoH8hAmI1IRbuVtq3GSTHwtRB/Kqhk= +github.com/ipfs/go-ipfs-cmds v0.4.0 h1:xUavIxA9Ts8U6PAHmQBvDGMlGfUrQ13Rymd+5t8LIF4= +github.com/ipfs/go-ipfs-cmds v0.4.0/go.mod h1:ZgYiWVnCk43ChwoH8hAmI1IRbuVtq3GSTHwtRB/Kqhk= github.com/ipfs/go-ipfs-config v0.9.0 h1:qTXJ9CyOyQv1LFJUMysxz8fi6RxxnP9QqcmiobuANvw= github.com/ipfs/go-ipfs-config v0.9.0/go.mod h1:GQUxqb0NfkZmEU92PxqqqLVVFTLpoGGUlBaTyDaAqrE= github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= From 2535f4de829d352ae47b56589dd2734cb69a193c Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Wed, 9 Sep 2020 13:43:33 -0400 Subject: [PATCH 009/116] Revert "fix: override GOFLAGS" This reverts commit 480defab689610550ee3d346e31441a2bb881fcb. --- mk/golang.mk | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/mk/golang.mk b/mk/golang.mk index 5d70f02baed..73073370194 100644 --- a/mk/golang.mk +++ b/mk/golang.mk @@ -6,13 +6,12 @@ export GO111MODULE=on # pre-definitions GOCC ?= go GOTAGS ?= +unexport GOFLAGS +GOFLAGS ?= GOTFLAGS ?= -# Unexport GOFLAGS so we only apply it where we actually want it. -unexport GOFLAGS # Try to make building as reproducible as possible by stripping the go path. -# Override so we can combine with the user's go flags. -override GOFLAGS += -trimpath +GOFLAGS += "-asmflags=all='-trimpath=$(GOPATH)'" "-gcflags=all='-trimpath=$(GOPATH)'" ifeq ($(tarball-is),1) GOFLAGS += -mod=vendor From 48b2f1273af310934d0e2334ce5460712e706200 Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Wed, 9 Sep 2020 13:48:36 -0400 Subject: [PATCH 010/116] fix: use override GOFLAGS changes from 480defab689610550ee3d346e31441a2bb881fcb but keep trimpath usage as is --- mk/golang.mk | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mk/golang.mk b/mk/golang.mk index 73073370194..210af085991 100644 --- a/mk/golang.mk +++ b/mk/golang.mk @@ -6,12 +6,13 @@ export GO111MODULE=on # pre-definitions GOCC ?= go GOTAGS ?= -unexport GOFLAGS -GOFLAGS ?= GOTFLAGS ?= +# Unexport GOFLAGS so we only apply it where we actually want it. +unexport GOFLAGS +# Override so we can combine with the user's go flags. # Try to make building as reproducible as possible by stripping the go path. -GOFLAGS += "-asmflags=all='-trimpath=$(GOPATH)'" "-gcflags=all='-trimpath=$(GOPATH)'" +override GOFLAGS += "-asmflags=all='-trimpath=$(GOPATH)'" "-gcflags=all='-trimpath=$(GOPATH)'" ifeq ($(tarball-is),1) GOFLAGS += -mod=vendor From 76892f5c2f1acbf8af560e6b8e8aef47eb2770fb Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Fri, 4 Sep 2020 18:51:55 +0200 Subject: [PATCH 011/116] docs(config): X-Forwarded-Host This fixes a bug and documents X-Forwarded-Host License: MIT Signed-off-by: Marcin Rataj --- docs/config.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/config.md b/docs/config.md index 274280b0404..6119098f8d7 100644 --- a/docs/config.md +++ b/docs/config.md @@ -702,11 +702,11 @@ Below is a list of the most common public gateway setups. } }' ``` - **Note I:** this enables automatic redirects from content paths to subdomains: + **Backward-compatible:** this feature enables automatic redirects from content paths to subdomains: `http://dweb.link/ipfs/{cid}` → `http://{cid}.ipfs.dweb.link` - **Note II:** 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://`. The NGINX directive is `proxy_set_header X-Forwarded-Proto "https";`.: + **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://`. The NGINX directive is `proxy_set_header X-Forwarded-Proto "https";`.: `http://dweb.link/ipfs/{cid}` → `https://{cid}.ipfs.dweb.link` - **Note III:** we also support `X-Forwarded-Proto: example.com` if you want to override subdomain gateway host from the original request: + **X-Forwarded-Host:** we also support `X-Forwarded-Host: example.com` if you want to override subdomain gateway host from the original request: `http://dweb.link/ipfs/{cid}` → `http://{cid}.ipfs.example.com` From fd01acdfc0cede60706d59cfdeaa9784c8f7c8f3 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Wed, 16 Sep 2020 22:10:36 +0200 Subject: [PATCH 012/116] feat(gateway): ?filename with download=true This implements 'attachment' mode triggered then ?filename parameter is accompanied with &download=true When Content-Disposition: attachment is detected by a modern browser it will skip rendering and immediately open the "save as" dialog, making this useful feature for using IPFS gateway as target of "Download" links on various websites. Parameter name was suggested in: https://github.com/ipfs/go-ipfs/pull/4177#issuecomment-414870327 --- core/corehttp/gateway_handler.go | 6 +++++- docs/gateway.md | 10 ++++++++++ test/sharness/t0110-gateway.sh | 7 ++++++- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/core/corehttp/gateway_handler.go b/core/corehttp/gateway_handler.go index b9e7f144b9d..0c708f87be4 100644 --- a/core/corehttp/gateway_handler.go +++ b/core/corehttp/gateway_handler.go @@ -261,7 +261,11 @@ func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request urlFilename := r.URL.Query().Get("filename") var name string if urlFilename != "" { - w.Header().Set("Content-Disposition", fmt.Sprintf("inline; filename*=UTF-8''%s", url.PathEscape(urlFilename))) + disposition := "inline" + if r.URL.Query().Get("download") == "true" { + disposition = "attachment" + } + w.Header().Set("Content-Disposition", fmt.Sprintf("%s; filename*=UTF-8''%s", disposition, url.PathEscape(urlFilename))) name = urlFilename } else { name = getFilename(urlPath) diff --git a/docs/gateway.md b/docs/gateway.md index 2344ee55ea8..dab41e09171 100644 --- a/docs/gateway.md +++ b/docs/gateway.md @@ -49,6 +49,16 @@ your query string to explicitly specify the filename. For example: > https://ipfs.io/ipfs/QmfM2r8seH2GiRaC4esTjeraXEachRt8ZsSeGaWTPLyMoG?filename=hello_world.txt +When you try to save above page, you browser will use passed `filename` instead of a CID. + +## Downloads + +It is possible to skip browser rendering of supported filetypes (plain text, +images, audio, video, PDF) and trigger immediate "save as" dialog by appending +`&download=true`: + +> https://ipfs.io/ipfs/QmfM2r8seH2GiRaC4esTjeraXEachRt8ZsSeGaWTPLyMoG?filename=hello_world.txt&download=true + ## MIME-Types TODO diff --git a/test/sharness/t0110-gateway.sh b/test/sharness/t0110-gateway.sh index 2a1f58c71a4..3880880c274 100755 --- a/test/sharness/t0110-gateway.sh +++ b/test/sharness/t0110-gateway.sh @@ -31,11 +31,16 @@ test_expect_success "GET IPFS path succeeds" ' curl -sfo actual "http://127.0.0.1:$port/ipfs/$HASH" ' -test_expect_success "GET IPFS path with explicit filename succeeds with proper header" " +test_expect_success "GET IPFS path with explicit ?filename succeeds with proper header" " curl -fo actual -D actual_headers 'http://127.0.0.1:$port/ipfs/$HASH?filename=testтест' && grep -F \"Content-Disposition: inline; filename*=UTF-8''test%D1%82%D0%B5%D1%81%D1%82\" actual_headers " +test_expect_success "GET IPFS path with explicit ?filename and download=true succeeds with proper header" " + curl -fo actual -D actual_headers 'http://127.0.0.1:$port/ipfs/$HASH?filename=testтест&download=true' && + grep -F \"Content-Disposition: attachment; filename*=UTF-8''test%D1%82%D0%B5%D1%81%D1%82\" actual_headers +" + # https://github.com/ipfs/go-ipfs/issues/4025#issuecomment-342250616 test_expect_success "GET for Service Worker registration outside of an IPFS content root errors" " curl -H 'Service-Worker: script' -svX GET 'http://127.0.0.1:$port/ipfs/$HASH?filename=sw.js' > curl_sw_out 2>&1 && From 19ec5f4a51e9c53c8d6b2df7d8472058d342b4c6 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Wed, 16 Sep 2020 22:39:04 +0200 Subject: [PATCH 013/116] feat(gateway): Content-Disposition for legacy clients This adds ASCII-only filename for clients that do not implement RFC 5987 Closes #7648 --- core/corehttp/gateway_handler.go | 6 +++++- test/sharness/t0110-gateway.sh | 10 +++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/core/corehttp/gateway_handler.go b/core/corehttp/gateway_handler.go index 0c708f87be4..b7a2b7e38c1 100644 --- a/core/corehttp/gateway_handler.go +++ b/core/corehttp/gateway_handler.go @@ -34,6 +34,8 @@ const ( ipnsPathPrefix = "/ipns/" ) +var onlyAscii = regexp.MustCompile("[[:^ascii:]]") + // gatewayHandler is a HTTP handler that serves IPFS objects (accessible by default at /ipfs/) // (it serves requests like GET /ipfs/QmVRzPKPzNtSrEzBFm2UZfxmPAgnaLke4DMcerbsGGSaFe/link) type gatewayHandler struct { @@ -265,7 +267,9 @@ func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request if r.URL.Query().Get("download") == "true" { disposition = "attachment" } - w.Header().Set("Content-Disposition", fmt.Sprintf("%s; filename*=UTF-8''%s", disposition, url.PathEscape(urlFilename))) + 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) diff --git a/test/sharness/t0110-gateway.sh b/test/sharness/t0110-gateway.sh index 3880880c274..032dfccc658 100755 --- a/test/sharness/t0110-gateway.sh +++ b/test/sharness/t0110-gateway.sh @@ -32,13 +32,13 @@ test_expect_success "GET IPFS path succeeds" ' ' test_expect_success "GET IPFS path with explicit ?filename succeeds with proper header" " - curl -fo actual -D actual_headers 'http://127.0.0.1:$port/ipfs/$HASH?filename=testтест' && - grep -F \"Content-Disposition: inline; filename*=UTF-8''test%D1%82%D0%B5%D1%81%D1%82\" actual_headers + curl -fo actual -D actual_headers 'http://127.0.0.1:$port/ipfs/$HASH?filename=testтест.pdf' && + grep -F 'Content-Disposition: inline; filename=\"test____.pdf\"; filename*=UTF-8'\'\''test%D1%82%D0%B5%D1%81%D1%82.pdf' actual_headers " -test_expect_success "GET IPFS path with explicit ?filename and download=true succeeds with proper header" " - curl -fo actual -D actual_headers 'http://127.0.0.1:$port/ipfs/$HASH?filename=testтест&download=true' && - grep -F \"Content-Disposition: attachment; filename*=UTF-8''test%D1%82%D0%B5%D1%81%D1%82\" actual_headers +test_expect_success "GET IPFS path with explicit ?filename and &download=true succeeds with proper header" " + curl -fo actual -D actual_headers 'http://127.0.0.1:$port/ipfs/$HASH?filename=testтест.mp4&download=true' && + grep -F 'Content-Disposition: attachment; filename=\"test____.mp4\"; filename*=UTF-8'\'\''test%D1%82%D0%B5%D1%81%D1%82.mp4' actual_headers " # https://github.com/ipfs/go-ipfs/issues/4025#issuecomment-342250616 From 16b3fd4d8752ad5422aed6348e2cc597b2e76584 Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Thu, 10 Sep 2020 15:53:19 -0400 Subject: [PATCH 014/116] fix: remove the (empty) alias for --peerid-base --- core/commands/id.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/commands/id.go b/core/commands/id.go index 1855425f878..83f3bb4b3ab 100644 --- a/core/commands/id.go +++ b/core/commands/id.go @@ -70,7 +70,7 @@ EXAMPLE: }, Options: []cmds.Option{ cmds.StringOption(formatOptionName, "f", "Optional output format."), - cmds.StringOption(idFormatOptionName, "", "Encoding used for peer IDs: Can either be a multibase encoded CID or a base58btc encoded multihash. Takes {b58mh|base36|k|base32|b...}.").WithDefault("b58mh"), + cmds.StringOption(idFormatOptionName, "Encoding used for peer IDs: Can either be a multibase encoded CID or a base58btc encoded multihash. Takes {b58mh|base36|k|base32|b...}.").WithDefault("b58mh"), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { keyEnc, err := ke.KeyEncoderFromString(req.Options[idFormatOptionName].(string)) From 1b4f5e72ad11c42e6a9e12b3799c97e17a0bb617 Mon Sep 17 00:00:00 2001 From: Rafael Ramalho Date: Thu, 10 Sep 2020 19:47:44 +0100 Subject: [PATCH 015/116] chore: bump webui version --- core/corehttp/webui.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/corehttp/webui.go b/core/corehttp/webui.go index 8eff65c2dfa..b0f4256c88f 100644 --- a/core/corehttp/webui.go +++ b/core/corehttp/webui.go @@ -1,11 +1,13 @@ package corehttp // TODO: move to IPNS -const WebUIPath = "/ipfs/bafybeihpetclqvwb4qnmumvcn7nh4pxrtugrlpw4jgjpqicdxsv7opdm6e" // v2.10.2 +const WebUIPath = "/ipfs/bafybeianwe4vy7sprht5sm3hshvxjeqhwcmvbzq73u55sdhqngmohkjgs4" // v2.11.1 // this is a list of all past webUI paths. var WebUIPaths = []string{ WebUIPath, + "/ipfs/bafybeicitin4p7ggmyjaubqpi3xwnagrwarsy6hiihraafk5rcrxqxju6m", + "/ipfs/bafybeihpetclqvwb4qnmumvcn7nh4pxrtugrlpw4jgjpqicdxsv7opdm6e", "/ipfs/bafybeibnnxd4etu4tq5fuhu3z5p4rfu3buabfkeyr3o3s4h6wtesvvw6mu", "/ipfs/bafybeid6luolenf4fcsuaw5rgdwpqbyerce4x3mi3hxfdtp5pwco7h7qyq", "/ipfs/bafybeigkbbjnltbd4ewfj7elajsbnjwinyk6tiilczkqsibf3o7dcr6nn4", From a6c15986122a09e545c04da013a5fca2833bf541 Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Mon, 21 Sep 2020 12:18:43 -0400 Subject: [PATCH 016/116] docs: update changelog for v0.7.0 --- CHANGELOG.md | 539 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 539 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e803b2a2b1e..63382740f89 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,544 @@ # go-ipfs changelog +## v0.7.0 2020-09-22 + +### Highlights + +#### Secio is now disabled by default + +As part of deprecating and removing support for the Secio security transport, we have disabled it by default. TLS1.3 will remain the default security transport with fallback to Noise. You can read more about the deprecation in the blog post, https://blog.ipfs.io/2020-08-07-deprecating-secio/. If you're running IPFS older than 0.5, this may start to impact your performance on the public network. + +#### Ed25519 keys are now used by default + +Previously go-ipfs generated 2048 bit RSA keys for new nodes, but it will now use ed25519 keys by default. This will not affect any existing keys, but newly created keys will be ed25519 by default. The main benefit of using ed25519 keys over RSA is that ed25519 keys have an inline public key. This means that someone only needs your PeerId to verify things you've signed, which means we don't have to worry about storing those bulky RSA public keys. + +##### Rotating keys + +Along with switching the default, we've added support for rotating keys. If you would like to change the key type of your IPFS node, you can now do so with the rotate command. **NOTE: This will affect your Peer Id, so be sure you want to do this!** Your existing identity key will be backed up in the Keystore. + +```bash +ipfs key rotate -o my-old-key -t ed25519 +``` + +#### Key export/import + +We've added commands to allow you to export and import keys from the IPFS Keystore to a local .key file. This does not apply to the IPFS identity key, `self`. + +```bash +ipfs key gen mykey +ipfs key export -o mykey.key mykey # ./.key is the default path +ipfs key import mykey mykey.key # on another node +``` + +#### IPNS paths now encode the key name as a base36 CIDv1 by default + +Previously go-ipfs encoded the key names for IPNS paths as base58btc multihashes (e.g. Qmabc...). We now encode them as base36 encoded CIDv1s as defined in the [peerID spec](https://github.com/libp2p/specs/blob/master/peer-ids/peer-ids.md#string-representation) (e.g. k51xyz...) which also deals with encoding of public keys. This is nice because it means that IPNS keys will by default be case-insensitive and that they will fit into DNS labels (e.g. k51xyz...ipns.localhost) and therefore that subdomain gateway redirections (e.g. from localhost:8080/ipns/{key} to {key}.ipns.localhost) will look better to users in the default case. + +Many commands will accept a `--ipns-base` option that allows changing command outputs to use a particular encoding (i.e. base58btc multihash, or CIDv1 encoded in any supported base) + +#### Multiaddresses now accept PeerIDs encoded as CIDv1 + +In preparation for eventually changing the default PeerID representation multiaddresses can now contain strings like `/p2p/k51xyz...` in addition to the default `/p2p/Qmabc...`. There is a corresponding `--peerid-base` option to many functions that output peerIDs. + +#### `dag stat` + +Initial support has been added for the `ipfs dag stat` command. Running this command will traverse the DAG for the given root CID and report statistics. By default, progress will be shown as the DAG is traversed. Supported statistics currently include DAG size and number of blocks. + +```bash +ipfs dag stat bafybeihpetclqvwb4qnmumvcn7nh4pxrtugrlpw4jgjpqicdxsv7opdm6e # the IPFS webui +Size: 30362191, NumBlocks: 346 +``` + +#### Plugin build changes + +We have changed the build flags used by the official binary distributions on dist.ipfs.io (or `/ipns/dist.ipfs.io`) to use the simpler and more reliable `-trimpath` flag instead of the more complicated and brittle `-asmflags=all=-trimpath="$(GOPATH)" -gcflags=all=-trimpath="$(GOPATH)"` flags, however the build flags used by default in go-ipfs remain the same. + +The scripts in https://github.com/ipfs/go-ipfs-example-plugin have been updated to reflect this change. This is a breaking change to how people have been building plugins against the dist.ipfs.io binary of go-ipfs and plugins should update their build processes accordingly see https://github.com/ipfs/go-ipfs-example-plugin/pull/9 for details. + +### Changelog + +- github.com/ipfs/go-ipfs: + - chore: bump webui version + - fix: remove the (empty) alias for --peerid-base + - Release v0.7.0-rc2 + - fix: use override GOFLAGS changes from 480defab689610550ee3d346e31441a2bb881fcb but keep trimpath usage as is + - Revert "fix: override GOFLAGS" + - fix: remove the (empty) alias for --ipns-base + - refactor: put all --ipns-base options in one place + - docs: update config to indicate SECIO deprecation + - fix: ipfs dht put/get commands now work on keys encoded as peerIDs and fail early for namespaces other than /pk or /ipns + - Release v0.7.0-rc1 + - chore: cleanup ([ipfs/go-ipfs#7628](https://github.com/ipfs/go-ipfs/pull/7628)) + - namesys: fixed IPNS republisher to not overwrite IPNS record lifetimes ([ipfs/go-ipfs#7627](https://github.com/ipfs/go-ipfs/pull/7627)) + - Fix #7624: Do not fetch dag nodes when checking if a pin exists ([ipfs/go-ipfs#7625](https://github.com/ipfs/go-ipfs/pull/7625)) + - chore: update dependencies ([ipfs/go-ipfs#7610](https://github.com/ipfs/go-ipfs/pull/7610)) + - use t.Cleanup() to reduce the need to clean up servers in tests ([ipfs/go-ipfs#7550](https://github.com/ipfs/go-ipfs/pull/7550)) + - fix: ipfs pin ls - ignore pins that have errors ([ipfs/go-ipfs#7612](https://github.com/ipfs/go-ipfs/pull/7612)) + - docs(config): fix Peering header ([ipfs/go-ipfs#7623](https://github.com/ipfs/go-ipfs/pull/7623)) + - sharness: use dnsaddr example in ipfs p2p command tests ([ipfs/go-ipfs#7620](https://github.com/ipfs/go-ipfs/pull/7620)) + - fix(key): dont allow backup key to be named 'self' ([ipfs/go-ipfs#7615](https://github.com/ipfs/go-ipfs/pull/7615)) + - [BOUNTY] Directory page UI improvements ([ipfs/go-ipfs#7536](https://github.com/ipfs/go-ipfs/pull/7536)) + - fix: make assets deterministic ([ipfs/go-ipfs#7609](https://github.com/ipfs/go-ipfs/pull/7609)) + - use ed25519 keys by default ([ipfs/go-ipfs#7579](https://github.com/ipfs/go-ipfs/pull/7579)) + - feat: wildcard support for public gateways ([ipfs/go-ipfs#7319](https://github.com/ipfs/go-ipfs/pull/7319)) + - fix: fix go-bindata import path ([ipfs/go-ipfs#7605](https://github.com/ipfs/go-ipfs/pull/7605)) + - Upgrade graphsync deps ([ipfs/go-ipfs#7598](https://github.com/ipfs/go-ipfs/pull/7598)) + - Add --peerid-base to ipfs id command ([ipfs/go-ipfs#7591](https://github.com/ipfs/go-ipfs/pull/7591)) + - use b36 keys by default for keys and IPNS ([ipfs/go-ipfs#7582](https://github.com/ipfs/go-ipfs/pull/7582)) + - add ipfs dag stat command (#7553) ([ipfs/go-ipfs#7553](https://github.com/ipfs/go-ipfs/pull/7553)) + - Move key rotation command to ipfs key rotate ([ipfs/go-ipfs#7599](https://github.com/ipfs/go-ipfs/pull/7599)) + - Disable secio by default ([ipfs/go-ipfs#7600](https://github.com/ipfs/go-ipfs/pull/7600)) + - Stop searching for public keys before doing an IPNS Get (#7549) ([ipfs/go-ipfs#7549](https://github.com/ipfs/go-ipfs/pull/7549)) + - feat: return supported protocols in id output ([ipfs/go-ipfs#7409](https://github.com/ipfs/go-ipfs/pull/7409)) + - docs: fix typo in default swarm addrs config docs ([ipfs/go-ipfs#7585](https://github.com/ipfs/go-ipfs/pull/7585)) + - feat: nice errors when failing to load plugins ([ipfs/go-ipfs#7429](https://github.com/ipfs/go-ipfs/pull/7429)) + - doc: document reverse proxy bug ([ipfs/go-ipfs#7478](https://github.com/ipfs/go-ipfs/pull/7478)) + - fix: ipfs name resolve --dht-record-count flag uses correct type and now works + - refactor: get rid of cmdDetails awkwardness + - IPNS format keys in b36cid ([ipfs/go-ipfs#7554](https://github.com/ipfs/go-ipfs/pull/7554)) + - Key import and export cli commands ([ipfs/go-ipfs#7546](https://github.com/ipfs/go-ipfs/pull/7546)) + - feat: add snap package configuration ([ipfs/go-ipfs#7529](https://github.com/ipfs/go-ipfs/pull/7529)) + - chore: bump webui version + - repeat gateway subdomain test for all key types (#7542) ([ipfs/go-ipfs#7542](https://github.com/ipfs/go-ipfs/pull/7542)) + - fix: override GOFLAGS + - update QUIC, enable the RetireBugBackwardsCompatibilityMode + - Document add behavior when the daemon is not running ([ipfs/go-ipfs#7514](https://github.com/ipfs/go-ipfs/pull/7514)) + - ([ipfs/go-ipfs#7515](https://github.com/ipfs/go-ipfs/pull/7515)) + - Choose Key type at initialization ([ipfs/go-ipfs#7251](https://github.com/ipfs/go-ipfs/pull/7251)) + - feat: add flag to ipfs key and list to output keys in b36/CIDv1 (#7531) ([ipfs/go-ipfs#7531](https://github.com/ipfs/go-ipfs/pull/7531)) + - feat: support ED25519 libp2p-key in subdomains + - chore: fix a typo + - docs: document X-Forwarded-Host + - feat: support X-Forwarded-Host when doing gateway redirect + - chore: update test deps for graphsync + - chore: bump test dependencies ([ipfs/go-ipfs#7524](https://github.com/ipfs/go-ipfs/pull/7524)) + - fix: use static binaries in docker container ([ipfs/go-ipfs#7505](https://github.com/ipfs/go-ipfs/pull/7505)) + - chore:bump webui version to 2.10.1 ([ipfs/go-ipfs#7504](https://github.com/ipfs/go-ipfs/pull/7504)) + - chore: bump webui version ([ipfs/go-ipfs#7501](https://github.com/ipfs/go-ipfs/pull/7501)) + - update version to 0.7.0-dev + - Merge branch 'release' into master + - systemd: specify repo path, to avoid unnecessary subdirectory ([ipfs/go-ipfs#7472](https://github.com/ipfs/go-ipfs/pull/7472)) + - doc(prod): start documenting production stuff ([ipfs/go-ipfs#7469](https://github.com/ipfs/go-ipfs/pull/7469)) + - Readme: Update link about init systems (and import old readme) ([ipfs/go-ipfs#7473](https://github.com/ipfs/go-ipfs/pull/7473)) + - doc(config): expand peering docs ([ipfs/go-ipfs#7466](https://github.com/ipfs/go-ipfs/pull/7466)) + - fix: Use the -p option in Dockerfile to make parents as needed ([ipfs/go-ipfs#7464](https://github.com/ipfs/go-ipfs/pull/7464)) + - systemd: enable systemd hardening features ([ipfs/go-ipfs#7286](https://github.com/ipfs/go-ipfs/pull/7286)) + - fix(migration): migrate /ipfs/ bootstrappers to /p2p/ ([ipfs/go-ipfs#7450](https://github.com/ipfs/go-ipfs/pull/7450)) + - readme: update go-version ([ipfs/go-ipfs#7447](https://github.com/ipfs/go-ipfs/pull/7447)) + - fix(migration): correctly migrate quic addresses ([ipfs/go-ipfs#7446](https://github.com/ipfs/go-ipfs/pull/7446)) + - chore: add migration to listen on QUIC by default ([ipfs/go-ipfs#7443](https://github.com/ipfs/go-ipfs/pull/7443)) + - go: bump minimal dependency to 1.14.4 ([ipfs/go-ipfs#7419](https://github.com/ipfs/go-ipfs/pull/7419)) + - fix: use bitswap sessions for ipfs refs ([ipfs/go-ipfs#7389](https://github.com/ipfs/go-ipfs/pull/7389)) + - fix(commands): print consistent addresses in ipfs id ([ipfs/go-ipfs#7397](https://github.com/ipfs/go-ipfs/pull/7397)) + - fix two pubsub issues. ([ipfs/go-ipfs#7394](https://github.com/ipfs/go-ipfs/pull/7394)) + - docs: add pacman.store (@RubenKelevra) to the early testers ([ipfs/go-ipfs#7368](https://github.com/ipfs/go-ipfs/pull/7368)) + - Update docs-beta links to final URLs ([ipfs/go-ipfs#7386](https://github.com/ipfs/go-ipfs/pull/7386)) + - feat: webui v2.9.0 ([ipfs/go-ipfs#7387](https://github.com/ipfs/go-ipfs/pull/7387)) + - chore: update WebUI to 2.8.0 ([ipfs/go-ipfs#7380](https://github.com/ipfs/go-ipfs/pull/7380)) + - mailmap support ([ipfs/go-ipfs#7375](https://github.com/ipfs/go-ipfs/pull/7375)) + - doc: update the release template for git flow changes ([ipfs/go-ipfs#7370](https://github.com/ipfs/go-ipfs/pull/7370)) + - chore: update deps ([ipfs/go-ipfs#7369](https://github.com/ipfs/go-ipfs/pull/7369)) +- github.com/ipfs/go-bitswap (v0.2.19 -> v0.2.20): + - fix: don't say we're sending a full wantlist unless we are (#429) ([ipfs/go-bitswap#429](https://github.com/ipfs/go-bitswap/pull/429)) +- github.com/ipfs/go-cid (v0.0.6 -> v0.0.7): + - feat: optimize cid.Prefix ([ipfs/go-cid#109](https://github.com/ipfs/go-cid/pull/109)) +- github.com/ipfs/go-datastore (v0.4.4 -> v0.4.5): + - Add test to ensure that Delete returns no error for missing keys ([ipfs/go-datastore#162](https://github.com/ipfs/go-datastore/pull/162)) + - Fix typo in sync/sync.go ([ipfs/go-datastore#159](https://github.com/ipfs/go-datastore/pull/159)) + - Add the generated flatfs stub, since it cannot be auto-generated ([ipfs/go-datastore#158](https://github.com/ipfs/go-datastore/pull/158)) + - support flatfs fuzzing ([ipfs/go-datastore#157](https://github.com/ipfs/go-datastore/pull/157)) + - fuzzing harness (#153) ([ipfs/go-datastore#153](https://github.com/ipfs/go-datastore/pull/153)) + - feat(mount): don't give up on error ([ipfs/go-datastore#146](https://github.com/ipfs/go-datastore/pull/146)) + - /test: fix bad ElemCount/10 lenght (should not be divided) ([ipfs/go-datastore#152](https://github.com/ipfs/go-datastore/pull/152)) +- github.com/ipfs/go-ds-flatfs (v0.4.4 -> v0.4.5): + - Add os.Rename wrapper for Plan 9 (#87) ([ipfs/go-ds-flatfs#87](https://github.com/ipfs/go-ds-flatfs/pull/87)) +- github.com/ipfs/go-fs-lock (v0.0.5 -> v0.0.6): + - Fix build on Plan 9 ([ipfs/go-fs-lock#17](https://github.com/ipfs/go-fs-lock/pull/17)) +- github.com/ipfs/go-graphsync (v0.0.5 -> v0.1.1): + - docs(CHANGELOG): update for v0.1.1 + - docs(CHANGELOG): update for v0.1.0 release ([ipfs/go-graphsync#84](https://github.com/ipfs/go-graphsync/pull/84)) + - Dedup by key extension (#83) ([ipfs/go-graphsync#83](https://github.com/ipfs/go-graphsync/pull/83)) + - Release infrastructure (#81) ([ipfs/go-graphsync#81](https://github.com/ipfs/go-graphsync/pull/81)) + - feat(persistenceoptions): add unregister ability (#80) ([ipfs/go-graphsync#80](https://github.com/ipfs/go-graphsync/pull/80)) + - fix(message): regen protobuf code (#79) ([ipfs/go-graphsync#79](https://github.com/ipfs/go-graphsync/pull/79)) + - feat(requestmanager): run response hooks on completed requests (#77) ([ipfs/go-graphsync#77](https://github.com/ipfs/go-graphsync/pull/77)) + - Revert "add extensions on complete (#76)" + - add extensions on complete (#76) ([ipfs/go-graphsync#76](https://github.com/ipfs/go-graphsync/pull/76)) + - All changes to date including pause requests & start paused, along with new adds for cleanups and checking of execution (#75) ([ipfs/go-graphsync#75](https://github.com/ipfs/go-graphsync/pull/75)) + - More fine grained response controls (#71) ([ipfs/go-graphsync#71](https://github.com/ipfs/go-graphsync/pull/71)) + - Refactor request execution and use IPLD SkipMe functionality for proper partial results on a request (#70) ([ipfs/go-graphsync#70](https://github.com/ipfs/go-graphsync/pull/70)) + - feat(graphsync): implement do-no-send-cids extension (#69) ([ipfs/go-graphsync#69](https://github.com/ipfs/go-graphsync/pull/69)) + - Incoming Block Hooks (#68) ([ipfs/go-graphsync#68](https://github.com/ipfs/go-graphsync/pull/68)) + - fix(responsemanager): add nil check (#67) ([ipfs/go-graphsync#67](https://github.com/ipfs/go-graphsync/pull/67)) + - refactor(hooks): use external pubsub (#65) ([ipfs/go-graphsync#65](https://github.com/ipfs/go-graphsync/pull/65)) + - Update of IPLD Prime (#66) ([ipfs/go-graphsync#66](https://github.com/ipfs/go-graphsync/pull/66)) + - feat(responsemanager): add listener for completed responses (#64) ([ipfs/go-graphsync#64](https://github.com/ipfs/go-graphsync/pull/64)) + - Update Requests (#63) ([ipfs/go-graphsync#63](https://github.com/ipfs/go-graphsync/pull/63)) + - Add pausing and unpausing of requests (#62) ([ipfs/go-graphsync#62](https://github.com/ipfs/go-graphsync/pull/62)) + - Outgoing Request Hooks, swapping persistence layers (#61) ([ipfs/go-graphsync#61](https://github.com/ipfs/go-graphsync/pull/61)) + - Feat/request hook loader chooser (#60) ([ipfs/go-graphsync#60](https://github.com/ipfs/go-graphsync/pull/60)) + - Option to Reject requests by default (#58) ([ipfs/go-graphsync#58](https://github.com/ipfs/go-graphsync/pull/58)) + - Testify refactor (#56) ([ipfs/go-graphsync#56](https://github.com/ipfs/go-graphsync/pull/56)) + - Switch To Circle CI (#57) ([ipfs/go-graphsync#57](https://github.com/ipfs/go-graphsync/pull/57)) + - fix(deps): go mod tidy + - docs(README): remove ipldbridge reference + - Tech Debt: Remove IPLD Bridge ([ipfs/go-graphsync#55](https://github.com/ipfs/go-graphsync/pull/55)) +- github.com/ipfs/go-ipfs-cmds (v0.2.9 -> v0.4.0): + - fix: allow requests from electron renderer (#201) ([ipfs/go-ipfs-cmds#201](https://github.com/ipfs/go-ipfs-cmds/pull/201)) + - refactor: move external command checks into commands lib (#198) ([ipfs/go-ipfs-cmds#198](https://github.com/ipfs/go-ipfs-cmds/pull/198)) + - Fix build on Plan 9 ([ipfs/go-ipfs-cmds#199](https://github.com/ipfs/go-ipfs-cmds/pull/199)) +- github.com/ipfs/go-ipfs-config (v0.8.0 -> v0.9.0): + - error if bit size specified with ed25519 keys (#105) ([ipfs/go-ipfs-config#105](https://github.com/ipfs/go-ipfs-config/pull/105)) +- github.com/ipfs/go-log/v2 (v2.0.8 -> v2.1.1): + failed to fetch repo +- github.com/ipfs/go-path (v0.0.7 -> v0.0.8): + - ResolveToLastNode no longer fetches nodes it does not need ([ipfs/go-path#30](https://github.com/ipfs/go-path/pull/30)) + - doc: add a lead maintainer +- github.com/ipfs/interface-go-ipfs-core (v0.3.0 -> v0.4.0): + - Add ID formatting functions, used by various IPFS cli commands ([ipfs/interface-go-ipfs-core#65](https://github.com/ipfs/interface-go-ipfs-core/pull/65)) +- github.com/ipld/go-car (v0.1.0 -> v0.1.1-0.20200429200904-c222d793c339): + - Update go-ipld-prime to the era of NodeAssembler. ([ipld/go-car#31](https://github.com/ipld/go-car/pull/31)) + - fix: update the cli tool's car dep ([ipld/go-car#30](https://github.com/ipld/go-car/pull/30)) +- github.com/ipld/go-ipld-prime (v0.0.2-0.20191108012745-28a82f04c785 -> v0.0.2-0.20200428162820-8b59dc292b8e): + - Add two basic examples of usage, as go tests. + - Fix marshalling error ([ipld/go-ipld-prime#53](https://github.com/ipld/go-ipld-prime/pull/53)) + - Add more test specs for list and map nesting. + - traversal.SkipMe feature ([ipld/go-ipld-prime#51](https://github.com/ipld/go-ipld-prime/pull/51)) + - Improvements to traversal docs. + - Drop code coverage bot config. ([ipld/go-ipld-prime#50](https://github.com/ipld/go-ipld-prime/pull/50)) + - Promote NodeAssembler/NodeStyle interface rework to core, and use improved basicnode implementation. ([ipld/go-ipld-prime#49](https://github.com/ipld/go-ipld-prime/pull/49)) + - Merge branch 'traversal-benchmarks' + - Merge branch 'cycle-breaking-and-traversal-benchmarks' + - Merge branch 'assembler-upgrade-to-codecs' + - Path clarifications ([ipld/go-ipld-prime#47](https://github.com/ipld/go-ipld-prime/pull/47)) + - Merge branch 'research-admissions' + - Add a typed link node to allow traversal with code gen'd builders across links ([ipld/go-ipld-prime#41](https://github.com/ipld/go-ipld-prime/pull/41)) + - Merge branch 'research-admissions' + - Library updates. + - Feat/add code gen disclaimer ([ipld/go-ipld-prime#39](https://github.com/ipld/go-ipld-prime/pull/39)) + - Readme and key Node interface docs improvements. + - fix(schema/gen): return value not reference ([ipld/go-ipld-prime#38](https://github.com/ipld/go-ipld-prime/pull/38)) +- github.com/ipld/go-ipld-prime-proto (v0.0.0-20191113031812-e32bd156a1e5 -> v0.0.0-20200428191222-c1ffdadc01e1): + - feat(deps): upgrade to new IPLD prime ([ipld/go-ipld-prime-proto#1](https://github.com/ipld/go-ipld-prime-proto/pull/1)) + - Update to latest ipld before rework ([ipld/go-ipld-prime-proto#2](https://github.com/ipld/go-ipld-prime-proto/pull/2)) +- github.com/libp2p/go-libp2p (v0.9.6 -> v0.11.0): + - Added parsing of IPv6 addresses for incoming mDNS requests ([libp2p/go-libp2p#990](https://github.com/libp2p/go-libp2p/pull/990)) + - Switch from SECIO to Noise ([libp2p/go-libp2p#972](https://github.com/libp2p/go-libp2p/pull/972)) + - fix tests ([libp2p/go-libp2p#995](https://github.com/libp2p/go-libp2p/pull/995)) + - Bump Autonat version & validate fixed call loop in `.Addrs` (#988) ([libp2p/go-libp2p#988](https://github.com/libp2p/go-libp2p/pull/988)) + - fix: use the correct external address when NAT port-mapping ([libp2p/go-libp2p#987](https://github.com/libp2p/go-libp2p/pull/987)) + - upgrade deps + interoperable uvarint delimited writer/reader. (#985) ([libp2p/go-libp2p#985](https://github.com/libp2p/go-libp2p/pull/985)) + - fix host can be dialed by autonat public addr, but lost the public addr to announce ([libp2p/go-libp2p#983](https://github.com/libp2p/go-libp2p/pull/983)) + - Fix address advertisement bugs (#974) ([libp2p/go-libp2p#974](https://github.com/libp2p/go-libp2p/pull/974)) + - fix: avoid a close deadlock in the natmanager ([libp2p/go-libp2p#971](https://github.com/libp2p/go-libp2p/pull/971)) + - upgrade swarm; add ID() on mock conns and streams. (#970) ([libp2p/go-libp2p#970](https://github.com/libp2p/go-libp2p/pull/970)) +- github.com/libp2p/go-libp2p-asn-util (null -> v0.0.0-20200825225859-85005c6cf052): + - chore: go fmt + - feat: use deferred initialization of the asnStore ([libp2p/go-libp2p-asn-util#3](https://github.com/libp2p/go-libp2p-asn-util/pull/3)) + - chore: switch to forked cidranger + - fixed code + - library for ASN mappings +- github.com/libp2p/go-libp2p-autonat (v0.2.3 -> v0.3.2): + - static nat shouldn't call host.Addrs() + - upgrade deps + interoperable uvarint delimited writer/reader. (#95) ([libp2p/go-libp2p-autonat#95](https://github.com/libp2p/go-libp2p-autonat/pull/95)) + - fix: a type switch nit ([libp2p/go-libp2p-autonat#83](https://github.com/libp2p/go-libp2p-autonat/pull/83)) +- github.com/libp2p/go-libp2p-blankhost (v0.1.6 -> v0.2.0): + - call reset where appropriate (and update deps) ([libp2p/go-libp2p-blankhost#52](https://github.com/libp2p/go-libp2p-blankhost/pull/52)) +- github.com/libp2p/go-libp2p-circuit (v0.2.3 -> v0.3.1): + - upgrade deps + interoperable uvarints. (#122) ([libp2p/go-libp2p-circuit#122](https://github.com/libp2p/go-libp2p-circuit/pull/122)) + - Fix/remove deprecated logging ([libp2p/go-libp2p-circuit#85](https://github.com/libp2p/go-libp2p-circuit/pull/85)) +- github.com/libp2p/go-libp2p-core (v0.5.7 -> v0.6.1): + - experimental introspection support (#159) ([libp2p/go-libp2p-core#159](https://github.com/libp2p/go-libp2p-core/pull/159)) +- github.com/libp2p/go-libp2p-discovery (v0.4.0 -> v0.5.0): + - Put period at end of sentence ([libp2p/go-libp2p-discovery#65](https://github.com/libp2p/go-libp2p-discovery/pull/65)) +- github.com/libp2p/go-libp2p-kad-dht (v0.8.2 -> v0.9.0): + - chore: update deps ([libp2p/go-libp2p-kad-dht#689](https://github.com/libp2p/go-libp2p-kad-dht/pull/689)) + - allow overwriting builtin dual DHT options ([libp2p/go-libp2p-kad-dht#688](https://github.com/libp2p/go-libp2p-kad-dht/pull/688)) + - Hardening Improvements: RT diversity and decreased RT churn ([libp2p/go-libp2p-kad-dht#687](https://github.com/libp2p/go-libp2p-kad-dht/pull/687)) + - Fix key log encoding ([libp2p/go-libp2p-kad-dht#682](https://github.com/libp2p/go-libp2p-kad-dht/pull/682)) + - upgrade deps + uvarint delimited writer/reader. (#684) ([libp2p/go-libp2p-kad-dht#684](https://github.com/libp2p/go-libp2p-kad-dht/pull/684)) + - periodicBootstrapInterval should be ticker? (#678) ([libp2p/go-libp2p-kad-dht#678](https://github.com/libp2p/go-libp2p-kad-dht/pull/678)) + - removes duplicate comment ([libp2p/go-libp2p-kad-dht#674](https://github.com/libp2p/go-libp2p-kad-dht/pull/674)) + - Revert "Peer Diversity in the Routing Table (#658)" ([libp2p/go-libp2p-kad-dht#670](https://github.com/libp2p/go-libp2p-kad-dht/pull/670)) + - Fixed problem with refresh logging ([libp2p/go-libp2p-kad-dht#667](https://github.com/libp2p/go-libp2p-kad-dht/pull/667)) + - feat: protect all peers in low buckets, tag everyone else with 5 ([libp2p/go-libp2p-kad-dht#666](https://github.com/libp2p/go-libp2p-kad-dht/pull/666)) + - Peer Diversity in the Routing Table (#658) ([libp2p/go-libp2p-kad-dht#658](https://github.com/libp2p/go-libp2p-kad-dht/pull/658)) +- github.com/libp2p/go-libp2p-kbucket (v0.4.2 -> v0.4.7): + - chore: switch from go-multiaddr-net to go-multiaddr/net + - Use crypto/rand for generating random prefixes + - feat: when using the diversity filter for ipv6 addresses if the ASN cannot be found for a particular address then fallback on using the /32 mask of the address as the group name instead of simply rejecting the peer from routing table + - simplify filter (#92) ([libp2p/go-libp2p-kbucket#92](https://github.com/libp2p/go-libp2p-kbucket/pull/92)) + - fix: switch to forked cid ranger dep ([libp2p/go-libp2p-kbucket#91](https://github.com/libp2p/go-libp2p-kbucket/pull/91)) + - Reduce Routing Table churn (#90) ([libp2p/go-libp2p-kbucket#90](https://github.com/libp2p/go-libp2p-kbucket/pull/90)) + - Peer Diversity for Routing Table and Querying (#88) ([libp2p/go-libp2p-kbucket#88](https://github.com/libp2p/go-libp2p-kbucket/pull/88)) + - fix bug in peer eviction (#87) ([libp2p/go-libp2p-kbucket#87](https://github.com/libp2p/go-libp2p-kbucket/pull/87)) + - feat: add an AddedAt timestamp (#84) ([libp2p/go-libp2p-kbucket#84](https://github.com/libp2p/go-libp2p-kbucket/pull/84)) +- github.com/libp2p/go-libp2p-pubsub (v0.3.1 -> v0.3.5): + - regenerate protobufs (#381) ([libp2p/go-libp2p-pubsub#381](https://github.com/libp2p/go-libp2p-pubsub/pull/381)) + - track validation time + - fullfill promise as soon as a message begins validation + - don't apply penalty in self origin rejections + - add behaviour penalty threshold + - Add String() method to Topic. + - add regression test for issue 371 + - don't add direct peers to fanout + - reference spec change in comment. + - fix backoff slack time + - use the heartbeat interval for slack time + - add slack time to prune backoff clearance + - fix: call the correct tracer function in FloodSubRouter.Leave (#373) ([libp2p/go-libp2p-pubsub#373](https://github.com/libp2p/go-libp2p-pubsub/pull/373)) + - downgrade trace buffer overflow log to debug + - track topics in Reject/Duplicate/Deliver events + - add topics to Reject/Duplicate/Deliver events + - fix flaky test + - refactor ip colocation factor computation that is common for score and inspection + - better handling of intermediate topic score snapshots + - disallow duplicate score inspectors + - make peer score inspect function types aliases + - extended peer score inspection + - upgrade deps + interoperable uvarint delimited writer/reader. + - Add warning about messageIDs + - Signing policy + optional Signature, From and Seqno ([libp2p/go-libp2p-pubsub#359](https://github.com/libp2p/go-libp2p-pubsub/pull/359)) + - Update pubsub.go + - Define a public error ErrSubscriptionCancelled. + - only do PX on leave if PX was enabled in the node + - drop warning about failure to open stream to a debug log + - reinstate tagging (now protection) tests + - disable tests for direct/mesh tags, we don't have an interface to query the connman yet + - protect direct and mesh peers in the connection manager + - feat: add direct connect ticks option +- github.com/libp2p/go-libp2p-pubsub-router (v0.3.0 -> v0.3.2): + - upgrade deps + interoperable uvarint delimited writer/reader. (#79) ([libp2p/go-libp2p-pubsub-router#79](https://github.com/libp2p/go-libp2p-pubsub-router/pull/79)) +- github.com/libp2p/go-libp2p-quic-transport (v0.6.0 -> v0.8.0): + - update quic-go to v0.18.0 (#171) ([libp2p/go-libp2p-quic-transport#171](https://github.com/libp2p/go-libp2p-quic-transport/pull/171)) +- github.com/libp2p/go-libp2p-swarm (v0.2.6 -> v0.2.8): + - slim down dependencies ([libp2p/go-libp2p-swarm#225](https://github.com/libp2p/go-libp2p-swarm/pull/225)) + - `ID()` method on connections and streams + record opening time (#224) ([libp2p/go-libp2p-swarm#224](https://github.com/libp2p/go-libp2p-swarm/pull/224)) +- github.com/libp2p/go-libp2p-testing (v0.1.1 -> v0.2.0): + - Add net benchmark harness ([libp2p/go-libp2p-testing#21](https://github.com/libp2p/go-libp2p-testing/pull/21)) + - Update suite to check that streams respect mux.ErrReset. ([libp2p/go-libp2p-testing#16](https://github.com/libp2p/go-libp2p-testing/pull/16)) +- github.com/libp2p/go-maddr-filter (v0.0.5 -> v0.1.0): + - deprecate this package; moved to multiformats/go-multiaddr. (#23) ([libp2p/go-maddr-filter#23](https://github.com/libp2p/go-maddr-filter/pull/23)) + - chore(dep): update ([libp2p/go-maddr-filter#18](https://github.com/libp2p/go-maddr-filter/pull/18)) +- github.com/libp2p/go-msgio (v0.0.4 -> v0.0.6): + - interoperable uvarints. (#21) ([libp2p/go-msgio#21](https://github.com/libp2p/go-msgio/pull/21)) + - upgrade deps + interoperable uvarint delimited writer/reader. (#20) ([libp2p/go-msgio#20](https://github.com/libp2p/go-msgio/pull/20)) +- github.com/libp2p/go-netroute (v0.1.2 -> v0.1.3): + - add Plan 9 support +- github.com/libp2p/go-openssl (v0.0.5 -> v0.0.7): + - make ed25519 less special ([libp2p/go-openssl#7](https://github.com/libp2p/go-openssl/pull/7)) + - Add required bindings to support openssl in libp2p-tls ([libp2p/go-openssl#6](https://github.com/libp2p/go-openssl/pull/6)) +- github.com/libp2p/go-reuseport (v0.0.1 -> v0.0.2): + - Fix build on Plan 9 ([libp2p/go-reuseport#79](https://github.com/libp2p/go-reuseport/pull/79)) + - farewell gx; thanks for serving us well. + - update readme badges + - remove Jenkinsfile. +- github.com/libp2p/go-reuseport-transport (v0.0.3 -> v0.0.4): + - Update go-netroute and go-reuseport for Plan 9 support + - Fix build on Plan 9 +- github.com/lucas-clemente/quic-go (v0.16.2 -> v0.18.0): + - create a milestone version for v0.18.x + - add Changelog entries for v0.17 ([lucas-clemente/quic-go#2726](https://github.com/lucas-clemente/quic-go/pull/2726)) + - regenerate the testdata certificate with SAN instead of CommonName ([lucas-clemente/quic-go#2723](https://github.com/lucas-clemente/quic-go/pull/2723)) + - make it possible to use multiple qtls versions at the same time, add support for Go 1.15 ([lucas-clemente/quic-go#2720](https://github.com/lucas-clemente/quic-go/pull/2720)) + - add fuzzing for transport parameters ([lucas-clemente/quic-go#2713](https://github.com/lucas-clemente/quic-go/pull/2713)) + - run golangci-lint on Github Actions ([lucas-clemente/quic-go#2700](https://github.com/lucas-clemente/quic-go/pull/2700)) + - disallow values above 2^60 for Config.MaxIncoming{Uni}Streams ([lucas-clemente/quic-go#2711](https://github.com/lucas-clemente/quic-go/pull/2711)) + - never send a value larger than 2^60 in MAX_STREAMS frames ([lucas-clemente/quic-go#2710](https://github.com/lucas-clemente/quic-go/pull/2710)) + - run the check for go generated files on Github Actions instead of Travis ([lucas-clemente/quic-go#2703](https://github.com/lucas-clemente/quic-go/pull/2703)) + - update QUIC draft version information in README ([lucas-clemente/quic-go#2715](https://github.com/lucas-clemente/quic-go/pull/2715)) + - remove Fuzzit badge from README ([lucas-clemente/quic-go#2714](https://github.com/lucas-clemente/quic-go/pull/2714)) + - use the correct return values in Fuzz() functions ([lucas-clemente/quic-go#2705](https://github.com/lucas-clemente/quic-go/pull/2705)) + - simplify the connection, rename it to sendConn ([lucas-clemente/quic-go#2707](https://github.com/lucas-clemente/quic-go/pull/2707)) + - update qpack to v0.2.0 ([lucas-clemente/quic-go#2704](https://github.com/lucas-clemente/quic-go/pull/2704)) + - remove redundant error check in the stream ([lucas-clemente/quic-go#2718](https://github.com/lucas-clemente/quic-go/pull/2718)) + - put back the packet buffer when parsing the connection ID fails ([lucas-clemente/quic-go#2708](https://github.com/lucas-clemente/quic-go/pull/2708)) + - update fuzzing code for oss-fuzz ([lucas-clemente/quic-go#2702](https://github.com/lucas-clemente/quic-go/pull/2702)) + - fix travis script ([lucas-clemente/quic-go#2701](https://github.com/lucas-clemente/quic-go/pull/2701)) + - remove Fuzzit from Travis config ([lucas-clemente/quic-go#2699](https://github.com/lucas-clemente/quic-go/pull/2699)) + - add a script to check if go generated files are correct ([lucas-clemente/quic-go#2692](https://github.com/lucas-clemente/quic-go/pull/2692)) + - only arm the application data PTO timer after the handshake is confirmed ([lucas-clemente/quic-go#2689](https://github.com/lucas-clemente/quic-go/pull/2689)) + - fix tracing of congestion state updates ([lucas-clemente/quic-go#2691](https://github.com/lucas-clemente/quic-go/pull/2691)) + - fix reading of flag values in integration tests ([lucas-clemente/quic-go#2690](https://github.com/lucas-clemente/quic-go/pull/2690)) + - remove ACK decimation ([lucas-clemente/quic-go#2599](https://github.com/lucas-clemente/quic-go/pull/2599)) + - add a metric for PTOs ([lucas-clemente/quic-go#2686](https://github.com/lucas-clemente/quic-go/pull/2686)) + - remove the H3_EARLY_RESPONSE error ([lucas-clemente/quic-go#2687](https://github.com/lucas-clemente/quic-go/pull/2687)) + - implement tracing for congestion state changes ([lucas-clemente/quic-go#2684](https://github.com/lucas-clemente/quic-go/pull/2684)) + - remove the N connection simulation from the Reno code ([lucas-clemente/quic-go#2682](https://github.com/lucas-clemente/quic-go/pull/2682)) + - remove the SSLR (slow start large reduction) experiment ([lucas-clemente/quic-go#2680](https://github.com/lucas-clemente/quic-go/pull/2680)) + - remove unused connectionStats counters from the Reno implementation ([lucas-clemente/quic-go#2683](https://github.com/lucas-clemente/quic-go/pull/2683)) + - add an integration test that randomly sets tracers ([lucas-clemente/quic-go#2679](https://github.com/lucas-clemente/quic-go/pull/2679)) + - privatize some methods in the congestion controller package ([lucas-clemente/quic-go#2681](https://github.com/lucas-clemente/quic-go/pull/2681)) + - fix out-of-bounds read when creating a multiplexed tracer ([lucas-clemente/quic-go#2678](https://github.com/lucas-clemente/quic-go/pull/2678)) + - run integration tests with qlog and metrics on CircleCI ([lucas-clemente/quic-go#2677](https://github.com/lucas-clemente/quic-go/pull/2677)) + - add a metric for closed connections ([lucas-clemente/quic-go#2676](https://github.com/lucas-clemente/quic-go/pull/2676)) + - trace packets that are sent outside of a connection ([lucas-clemente/quic-go#2675](https://github.com/lucas-clemente/quic-go/pull/2675)) + - trace dropped packets that are dropped before they are passed to any session ([lucas-clemente/quic-go#2670](https://github.com/lucas-clemente/quic-go/pull/2670)) + - add a metric for sent packets ([lucas-clemente/quic-go#2673](https://github.com/lucas-clemente/quic-go/pull/2673)) + - add a metric for lost packets ([lucas-clemente/quic-go#2672](https://github.com/lucas-clemente/quic-go/pull/2672)) + - simplify the Tracer interface by combining the TracerFor... methods ([lucas-clemente/quic-go#2671](https://github.com/lucas-clemente/quic-go/pull/2671)) + - add a metrics package using OpenCensus, trace connections ([lucas-clemente/quic-go#2646](https://github.com/lucas-clemente/quic-go/pull/2646)) + - add a multiplexer for the tracer ([lucas-clemente/quic-go#2665](https://github.com/lucas-clemente/quic-go/pull/2665)) + - introduce a type for stateless reset tokens ([lucas-clemente/quic-go#2668](https://github.com/lucas-clemente/quic-go/pull/2668)) + - log all reasons why a connection is closed ([lucas-clemente/quic-go#2669](https://github.com/lucas-clemente/quic-go/pull/2669)) + - add integration tests using faulty packet conns ([lucas-clemente/quic-go#2663](https://github.com/lucas-clemente/quic-go/pull/2663)) + - don't block sendQueue.Send() if the runloop already exited. ([lucas-clemente/quic-go#2656](https://github.com/lucas-clemente/quic-go/pull/2656)) + - move the SupportedVersions slice out of the wire.Header ([lucas-clemente/quic-go#2664](https://github.com/lucas-clemente/quic-go/pull/2664)) + - add a flag to disable conn ID generation and the check for retired conn IDs ([lucas-clemente/quic-go#2660](https://github.com/lucas-clemente/quic-go/pull/2660)) + - put the session in the packet handler map directly (for client sessions) ([lucas-clemente/quic-go#2667](https://github.com/lucas-clemente/quic-go/pull/2667)) + - don't send write error in CONNECTION_CLOSE frames ([lucas-clemente/quic-go#2666](https://github.com/lucas-clemente/quic-go/pull/2666)) + - reset the PTO count before setting the timer when dropping a PN space ([lucas-clemente/quic-go#2657](https://github.com/lucas-clemente/quic-go/pull/2657)) + - enforce that a connection ID is not retired in a packet that uses that connection ID ([lucas-clemente/quic-go#2651](https://github.com/lucas-clemente/quic-go/pull/2651)) + - don't retire the conn ID that's in use when receiving a retransmission ([lucas-clemente/quic-go#2652](https://github.com/lucas-clemente/quic-go/pull/2652)) + - fix flaky cancelation integration test ([lucas-clemente/quic-go#2649](https://github.com/lucas-clemente/quic-go/pull/2649)) + - fix crash when the qlog callbacks returns a nil io.WriteCloser ([lucas-clemente/quic-go#2648](https://github.com/lucas-clemente/quic-go/pull/2648)) + - fix flaky server test on Travis ([lucas-clemente/quic-go#2645](https://github.com/lucas-clemente/quic-go/pull/2645)) + - fix a typo in the logging package test suite + - introduce type aliases in the logging package ([lucas-clemente/quic-go#2643](https://github.com/lucas-clemente/quic-go/pull/2643)) + - rename frame fields to the names used in the draft ([lucas-clemente/quic-go#2644](https://github.com/lucas-clemente/quic-go/pull/2644)) + - split the qlog package into a logging and a qlog package, use a tracer interface in the quic.Config ([lucas-clemente/quic-go#2638](https://github.com/lucas-clemente/quic-go/pull/2638)) + - fix HTTP request writing if the Request.Body reads data and returns EOF ([lucas-clemente/quic-go#2642](https://github.com/lucas-clemente/quic-go/pull/2642)) + - handle Version Negotiation packets in the session ([lucas-clemente/quic-go#2640](https://github.com/lucas-clemente/quic-go/pull/2640)) + - increase the packet size of the client's Initial packet ([lucas-clemente/quic-go#2634](https://github.com/lucas-clemente/quic-go/pull/2634)) + - introduce an assertion in the server ([lucas-clemente/quic-go#2637](https://github.com/lucas-clemente/quic-go/pull/2637)) + - use the new qtls interface for (re)storing app data with a session state ([lucas-clemente/quic-go#2631](https://github.com/lucas-clemente/quic-go/pull/2631)) + - remove buffering of HTTP requests ([lucas-clemente/quic-go#2626](https://github.com/lucas-clemente/quic-go/pull/2626)) + - remove superfluous parameters logged when not doing 0-RTT ([lucas-clemente/quic-go#2632](https://github.com/lucas-clemente/quic-go/pull/2632)) + - return an infinite bandwidth if the RTT is zero ([lucas-clemente/quic-go#2636](https://github.com/lucas-clemente/quic-go/pull/2636)) + - drop support for Go 1.13 ([lucas-clemente/quic-go#2628](https://github.com/lucas-clemente/quic-go/pull/2628)) + - remove superfluos handleResetStreamFrame method on the stream ([lucas-clemente/quic-go#2623](https://github.com/lucas-clemente/quic-go/pull/2623)) + - implement a token-bucket pacing algorithm ([lucas-clemente/quic-go#2615](https://github.com/lucas-clemente/quic-go/pull/2615)) + - gracefully handle concurrent stream writes and cancellations ([lucas-clemente/quic-go#2624](https://github.com/lucas-clemente/quic-go/pull/2624)) + - log sent packets right before sending them out ([lucas-clemente/quic-go#2613](https://github.com/lucas-clemente/quic-go/pull/2613)) + - remove unused packet counter in the receivedPacketTracker ([lucas-clemente/quic-go#2611](https://github.com/lucas-clemente/quic-go/pull/2611)) + - rewrite the proxy to avoid packet reordering ([lucas-clemente/quic-go#2617](https://github.com/lucas-clemente/quic-go/pull/2617)) + - fix flaky INVALID_TOKEN integration test ([lucas-clemente/quic-go#2610](https://github.com/lucas-clemente/quic-go/pull/2610)) + - make DialEarly return EarlySession ([lucas-clemente/quic-go#2621](https://github.com/lucas-clemente/quic-go/pull/2621)) + - add debug logging to the packet handler map ([lucas-clemente/quic-go#2608](https://github.com/lucas-clemente/quic-go/pull/2608)) + - increase the minimum pacing delay to 1ms ([lucas-clemente/quic-go#2605](https://github.com/lucas-clemente/quic-go/pull/2605)) +- github.com/marten-seemann/qpack (v0.1.0 -> v0.2.0): + - don't reuse the encoder in the integration tests ([marten-seemann/qpack#18](https://github.com/marten-seemann/qpack/pull/18)) + - use Huffman encoding for field names and values ([marten-seemann/qpack#16](https://github.com/marten-seemann/qpack/pull/16)) + - add more tests for encoding using the static table ([marten-seemann/qpack#15](https://github.com/marten-seemann/qpack/pull/15)) + - Encoder uses the static table. ([marten-seemann/qpack#10](https://github.com/marten-seemann/qpack/pull/10)) + - add gofmt to golangci-lint + - update qifs to the current version ([marten-seemann/qpack#14](https://github.com/marten-seemann/qpack/pull/14)) + - use golangci-lint for linting ([marten-seemann/qpack#12](https://github.com/marten-seemann/qpack/pull/12)) + - add fuzzing ([marten-seemann/qpack#9](https://github.com/marten-seemann/qpack/pull/9)) + - update qifs + - use https protocol for submodule clone ([marten-seemann/qpack#7](https://github.com/marten-seemann/qpack/pull/7)) +- github.com/marten-seemann/qtls (v0.9.1 -> v0.10.0): + - add callbacks to store and restore app data along a session state + - remove support for Go 1.13 +- github.com/marten-seemann/qtls-go1-15 (null -> v0.1.0): + - use a prefix for client session cache keys + - add callbacks to store and restore app data along a session state + - don't use TLS 1.3 compatibility mode when using alternative record layer + - delete the session ticket after attempting 0-RTT + - reject 0-RTT when a different ALPN is chosen + - encode the ALPN into the session ticket + - add a field to the ConnectionState to tell if 0-RTT was used + - add a callback to tell the client about rejection of 0-RTT + - don't offer 0-RTT after a HelloRetryRequest + - add Accept0RTT to Config callback to decide if 0-RTT should be accepted + - add the option to encode application data into the session ticket + - export the 0-RTT write key + - abuse the nonce field of ClientSessionState to save max_early_data_size + - export the 0-RTT read key + - close connection if client attempts 0-RTT, but ticket didn't allow it + - encode the max early data size into the session ticket + - implement parsing of the early_data extension in the EncryptedExtensions + - add a tls.Config.MaxEarlyData option to enable 0-RTT + - accept TLS 1.3 cipher suites in Config.CipherSuites + - introduce a function on the connection to generate a session ticket + - add a config option to enforce selection of an application protocol + - export Conn.HandlePostHandshakeMessage + - export Alert + - reject Configs that set MaxVersion < 1.3 when using a record layer + - enforce TLS 1.3 when using an alternative record layer +- github.com/multiformats/go-multiaddr (v0.2.2 -> v0.3.1): + - dep: add "codependencies" for handling version conflicts ([multiformats/go-multiaddr#132](https://github.com/multiformats/go-multiaddr/pull/132)) + - Support /p2p addresses encoded as CIDs ([multiformats/go-multiaddr#130](https://github.com/multiformats/go-multiaddr/pull/130)) + - Merge go-multiaddr-net +- github.com/multiformats/go-multiaddr-net (v0.1.5 -> v0.2.0): + - Deprecate ([multiformats/go-multiaddr-net#72](https://github.com/multiformats/go-multiaddr-net/pull/72)) +- github.com/multiformats/go-multihash (v0.0.13 -> v0.0.14): + - fix: only register one blake2s length ([multiformats/go-multihash#129](https://github.com/multiformats/go-multihash/pull/129)) + - feat: add two filecoin hashes, without Sum() implementations ([multiformats/go-multihash#128](https://github.com/multiformats/go-multihash/pull/128)) + - feat: reduce blake2b allocations by special-casing the 256/512 variants ([multiformats/go-multihash#126](https://github.com/multiformats/go-multihash/pull/126)) +- github.com/multiformats/go-multistream (v0.1.1 -> v0.1.2): + - upgrade deps + interoperable varints. (#51) ([multiformats/go-multistream#51](https://github.com/multiformats/go-multistream/pull/51)) +- github.com/multiformats/go-varint (v0.0.5 -> v0.0.6): + - fix minor interoperability issues. (#6) ([multiformats/go-varint#6](https://github.com/multiformats/go-varint/pull/6)) +- github.com/warpfork/go-wish (v0.0.0-20190328234359-8b3e70f8e830 -> v0.0.0-20200122115046-b9ea61034e4a): + - Add ShouldBeSameTypeAs checker. + - Integration test update for go versions. +- github.com/whyrusleeping/cbor-gen (v0.0.0-20200123233031-1cdf64d27158 -> v0.0.0-20200402171437-3d27c146c105): + - Handle Nil values for cbg.Deferred ([whyrusleeping/cbor-gen#14](https://github.com/whyrusleeping/cbor-gen/pull/14)) + - add name of struct field to error messages + - Support uint64 pointers ([whyrusleeping/cbor-gen#13](https://github.com/whyrusleeping/cbor-gen/pull/13)) + - int64 support in map encoders ([whyrusleeping/cbor-gen#12](https://github.com/whyrusleeping/cbor-gen/pull/12)) + - Fix uint64 typed array gen ([whyrusleeping/cbor-gen#10](https://github.com/whyrusleeping/cbor-gen/pull/10)) + - Fix cbg self referencing import path ([whyrusleeping/cbor-gen#8](https://github.com/whyrusleeping/cbor-gen/pull/8)) + +### Contributors + +| Contributor | Commits | Lines ± | Files Changed | +|-------------|---------|---------|---------------| +| Marten Seemann | 156 | +16428/-42621 | 979 | +| hannahhoward | 42 | +15132/-9819 | 467 | +| Eric Myhre | 114 | +13709/-6898 | 586 | +| Steven Allen | 55 | +1211/-2714 | 95 | +| Adin Schmahmann | 54 | +1660/-783 | 117 | +| Petar Maymounkov | 23 | +1677/-671 | 75 | +| Aarsh Shah | 10 | +1926/-341 | 39 | +| Raúl Kripalani | 17 | +1134/-537 | 53 | +| Will | 1 | +841/-0 | 9 | +| rendaw | 3 | +425/-195 | 12 | +| Will Scott | 8 | +302/-229 | 15 | +| vyzo | 22 | +345/-166 | 23 | +| Fazlul Shahriar | 7 | +452/-44 | 19 | +| Peter Rabbitson | 1 | +353/-118 | 5 | +| Hector Sanjuan | 10 | +451/-3 | 14 | +| Marcin Rataj | 9 | +298/-106 | 16 | +| Łukasz Magiera | 4 | +329/-51 | 12 | +| RubenKelevra | 9 | +331/-7 | 12 | +| Michael Muré | 2 | +259/-69 | 6 | +| jstordeur | 1 | +252/-2 | 5 | +| Diederik Loerakker | 1 | +168/-35 | 7 | +| Tiger | 3 | +138/-52 | 8 | +| Kevin Neaton | 3 | +103/-21 | 9 | +| Rod Vagg | 1 | +50/-40 | 4 | +| Oli Evans | 4 | +60/-9 | 6 | +| achingbrain | 4 | +30/-30 | 5 | +| Cyril Fougeray | 2 | +34/-24 | 2 | +| Luke Tucker | 1 | +31/-1 | 2 | +| sandman | 2 | +23/-7 | 3 | +| Alan Shaw | 1 | +18/-9 | 2 | +| Jacob Heun | 4 | +13/-3 | 4 | +| Jessica Schilling | 3 | +7/-7 | 3 | +| Rafael Ramalho | 4 | +9/-4 | 4 | +| Jeromy Johnson | 2 | +6/-6 | 4 | +| Nick Cabatoff | 1 | +7/-2 | 1 | +| Stephen Solka | 1 | +1/-7 | 1 | +| Preston Van Loon | 2 | +6/-2 | 2 | +| Jakub Sztandera | 2 | +5/-2 | 2 | +| llx | 1 | +3/-3 | 1 | +| Adrian Lanzafame | 1 | +3/-3 | 1 | +| Yusef Napora | 1 | +3/-2 | 1 | +| Louis Thibault | 1 | +5/-0 | 1 | +| Martín Triay | 1 | +4/-0 | 1 | +| Hlib | 1 | +2/-2 | 1 | +| Shotaro Yamada | 1 | +2/-1 | 1 | +| phuslu | 1 | +1/-1 | 1 | +| Zero King | 1 | +1/-1 | 1 | +| Rüdiger Klaehn | 1 | +2/-0 | 1 | +| Nex | 1 | +1/-1 | 1 | +| Mark Gaiser | 1 | +1/-1 | 1 | +| Luflosi | 1 | +1/-1 | 1 | +| David Florness | 1 | +1/-1 | 1 | +| Dean Eigenmann | 1 | +0/-1 | 1 | + ## v0.6.0 2020-06-19 This is a relatively small release in terms of code changes, but it contains some significant changes to the IPFS protocol. From cac753bb1834b69709679463047e939040e07607 Mon Sep 17 00:00:00 2001 From: Fazlul Shahriar Date: Mon, 21 Sep 2020 18:08:25 -0400 Subject: [PATCH 017/116] fix build on Plan 9 Fixes #7575 Fixes #7671 --- cmd/ipfs/util/ulimit_test.go | 2 +- cmd/ipfswatch/ipfswatch_test.go | 2 ++ cmd/ipfswatch/main.go | 2 ++ cmd/seccat/seccat.go | 3 +-- cmd/seccat/seccat_plan9.go | 8 ++++++++ cmd/seccat/seccat_posix.go | 10 ++++++++++ core/commands/add.go | 2 +- core/commands/dag/dag.go | 2 +- core/commands/get.go | 2 +- fuse/ipns/ipns_test.go | 2 +- fuse/ipns/ipns_unix.go | 2 +- fuse/ipns/link_unix.go | 2 +- fuse/mount/fuse.go | 2 +- fuse/node/mount_notsupp.go | 2 +- fuse/node/mount_test.go | 2 +- fuse/node/mount_unix.go | 2 +- fuse/readonly/ipfs_test.go | 2 +- go.mod | 4 ++-- go.sum | 7 +++++++ 19 files changed, 44 insertions(+), 16 deletions(-) create mode 100644 cmd/seccat/seccat_plan9.go create mode 100644 cmd/seccat/seccat_posix.go diff --git a/cmd/ipfs/util/ulimit_test.go b/cmd/ipfs/util/ulimit_test.go index 2fe42198bfe..80862ee5852 100644 --- a/cmd/ipfs/util/ulimit_test.go +++ b/cmd/ipfs/util/ulimit_test.go @@ -1,4 +1,4 @@ -// +build !windows +// +build !windows,!plan9 package util diff --git a/cmd/ipfswatch/ipfswatch_test.go b/cmd/ipfswatch/ipfswatch_test.go index f698cfa91d0..f6a6f7eecb4 100644 --- a/cmd/ipfswatch/ipfswatch_test.go +++ b/cmd/ipfswatch/ipfswatch_test.go @@ -1,3 +1,5 @@ +// +build !plan9 + package main import ( diff --git a/cmd/ipfswatch/main.go b/cmd/ipfswatch/main.go index 73207785838..e0bd00e17dc 100644 --- a/cmd/ipfswatch/main.go +++ b/cmd/ipfswatch/main.go @@ -1,3 +1,5 @@ +// +build !plan9 + package main import ( diff --git a/cmd/seccat/seccat.go b/cmd/seccat/seccat.go index a7ca9c9ef49..21724b4c51d 100644 --- a/cmd/seccat/seccat.go +++ b/cmd/seccat/seccat.go @@ -243,8 +243,7 @@ func netcat(c io.ReadWriteCloser) { // wait until we exit. sigc := make(chan os.Signal, 1) - signal.Notify(sigc, syscall.SIGHUP, syscall.SIGINT, - syscall.SIGTERM, syscall.SIGQUIT) + signal.Notify(sigc, notifySignals...) select { case <-done: diff --git a/cmd/seccat/seccat_plan9.go b/cmd/seccat/seccat_plan9.go new file mode 100644 index 00000000000..3139500c5b3 --- /dev/null +++ b/cmd/seccat/seccat_plan9.go @@ -0,0 +1,8 @@ +package main + +import ( + "os" + "syscall" +) + +var notifySignals = []os.Signal{syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM} diff --git a/cmd/seccat/seccat_posix.go b/cmd/seccat/seccat_posix.go new file mode 100644 index 00000000000..92906db6250 --- /dev/null +++ b/cmd/seccat/seccat_posix.go @@ -0,0 +1,10 @@ +// +build !plan9 + +package main + +import ( + "os" + "syscall" +) + +var notifySignals = []os.Signal{syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT} diff --git a/core/commands/add.go b/core/commands/add.go index df8dd5f9bbb..1c4c8603004 100644 --- a/core/commands/add.go +++ b/core/commands/add.go @@ -10,12 +10,12 @@ import ( "github.com/ipfs/go-ipfs/core/commands/cmdenv" + "github.com/cheggaaa/pb" cmds "github.com/ipfs/go-ipfs-cmds" files "github.com/ipfs/go-ipfs-files" coreiface "github.com/ipfs/interface-go-ipfs-core" "github.com/ipfs/interface-go-ipfs-core/options" mh "github.com/multiformats/go-multihash" - pb "gopkg.in/cheggaaa/pb.v1" ) // ErrDepthLimitExceeded indicates that the max depth has been exceeded. diff --git a/core/commands/dag/dag.go b/core/commands/dag/dag.go index 4df6571cc83..24e40d83059 100644 --- a/core/commands/dag/dag.go +++ b/core/commands/dag/dag.go @@ -31,7 +31,7 @@ import ( //gipselector "github.com/ipld/go-ipld-prime/traversal/selector" //gipselectorbuilder "github.com/ipld/go-ipld-prime/traversal/selector/builder" - "gopkg.in/cheggaaa/pb.v1" + "github.com/cheggaaa/pb" ) const ( diff --git a/core/commands/get.go b/core/commands/get.go index 854ea1b6787..7087c71ca3d 100644 --- a/core/commands/get.go +++ b/core/commands/get.go @@ -14,11 +14,11 @@ import ( "github.com/ipfs/go-ipfs/core/commands/cmdenv" "github.com/ipfs/go-ipfs/core/commands/e" + "github.com/cheggaaa/pb" cmds "github.com/ipfs/go-ipfs-cmds" files "github.com/ipfs/go-ipfs-files" "github.com/ipfs/interface-go-ipfs-core/path" "github.com/whyrusleeping/tar-utils" - "gopkg.in/cheggaaa/pb.v1" ) var ErrInvalidCompressionLevel = errors.New("compression level must be between 1 and 9") diff --git a/fuse/ipns/ipns_test.go b/fuse/ipns/ipns_test.go index fe9e5a5ae8d..e9fce165403 100644 --- a/fuse/ipns/ipns_test.go +++ b/fuse/ipns/ipns_test.go @@ -1,4 +1,4 @@ -// +build !nofuse,!openbsd,!netbsd +// +build !nofuse,!openbsd,!netbsd,!plan9 package ipns diff --git a/fuse/ipns/ipns_unix.go b/fuse/ipns/ipns_unix.go index fa65c51c41d..b8caf0ca2fe 100644 --- a/fuse/ipns/ipns_unix.go +++ b/fuse/ipns/ipns_unix.go @@ -1,4 +1,4 @@ -// +build !nofuse,!openbsd,!netbsd +// +build !nofuse,!openbsd,!netbsd,!plan9 // package fuse/ipns implements a fuse filesystem that interfaces // with ipns, the naming system for ipfs. diff --git a/fuse/ipns/link_unix.go b/fuse/ipns/link_unix.go index 3cc9effd645..3be52da99b2 100644 --- a/fuse/ipns/link_unix.go +++ b/fuse/ipns/link_unix.go @@ -1,4 +1,4 @@ -// +build !nofuse,!openbsd,!netbsd +// +build !nofuse,!openbsd,!netbsd,!plan9 package ipns diff --git a/fuse/mount/fuse.go b/fuse/mount/fuse.go index 1c5f0d2ce8d..c317f5e7dc2 100644 --- a/fuse/mount/fuse.go +++ b/fuse/mount/fuse.go @@ -1,4 +1,4 @@ -// +build !nofuse,!windows,!openbsd,!netbsd +// +build !nofuse,!windows,!openbsd,!netbsd,!plan9 package mount diff --git a/fuse/node/mount_notsupp.go b/fuse/node/mount_notsupp.go index 847abb059f2..929cdf7df90 100644 --- a/fuse/node/mount_notsupp.go +++ b/fuse/node/mount_notsupp.go @@ -1,4 +1,4 @@ -// +build !nofuse,openbsd !nofuse,netbsd +// +build !nofuse,openbsd !nofuse,netbsd !nofuse,plan9 package node diff --git a/fuse/node/mount_test.go b/fuse/node/mount_test.go index 7b051453a90..2d1642cb9f4 100644 --- a/fuse/node/mount_test.go +++ b/fuse/node/mount_test.go @@ -1,4 +1,4 @@ -// +build !openbsd,!nofuse,!netbsd +// +build !openbsd,!nofuse,!netbsd,!plan9 package node diff --git a/fuse/node/mount_unix.go b/fuse/node/mount_unix.go index 8c89c94b670..5388333ac78 100644 --- a/fuse/node/mount_unix.go +++ b/fuse/node/mount_unix.go @@ -1,4 +1,4 @@ -// +build !windows,!openbsd,!netbsd,!nofuse +// +build !windows,!openbsd,!netbsd,!plan9,!nofuse package node diff --git a/fuse/readonly/ipfs_test.go b/fuse/readonly/ipfs_test.go index e6d38507e69..feb2d4ec454 100644 --- a/fuse/readonly/ipfs_test.go +++ b/fuse/readonly/ipfs_test.go @@ -1,4 +1,4 @@ -// +build !nofuse,!openbsd,!netbsd +// +build !nofuse,!openbsd,!netbsd,!plan9 package readonly diff --git a/go.mod b/go.mod index c22d959dada..52161cb35c9 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ require ( github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect github.com/blang/semver v3.5.1+incompatible github.com/bren2010/proquint v0.0.0-20160323162903-38337c27106d + github.com/cheggaaa/pb v1.0.29 github.com/coreos/go-systemd/v22 v22.1.0 github.com/dustin/go-humanize v1.0.0 github.com/elgris/jsondiff v0.0.0-20160530203242-765b5c24c302 @@ -22,7 +23,7 @@ require ( github.com/ipfs/go-cidutil v0.0.2 github.com/ipfs/go-datastore v0.4.5 github.com/ipfs/go-detect-race v0.0.1 - github.com/ipfs/go-ds-badger v0.2.4 + github.com/ipfs/go-ds-badger v0.2.5 github.com/ipfs/go-ds-flatfs v0.4.5 github.com/ipfs/go-ds-leveldb v0.4.2 github.com/ipfs/go-ds-measure v0.1.0 @@ -107,7 +108,6 @@ require ( golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 golang.org/x/tools v0.0.0-20200522201501-cb1345f3a375 // indirect - gopkg.in/cheggaaa/pb.v1 v1.0.28 ) go 1.13 diff --git a/go.sum b/go.sum index b615e827333..3343569c9a0 100644 --- a/go.sum +++ b/go.sum @@ -85,6 +85,8 @@ github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+ github.com/cespare/xxhash/v2 v2.1.1/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= +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= @@ -119,6 +121,8 @@ github.com/dgraph-io/badger v1.6.0 h1:DshxFxZWXUcO0xX476VJC07Xsr6ZCBVRHKZ93Oh7Ev github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= github.com/dgraph-io/badger v1.6.1 h1:w9pSFNSdq/JPM1N12Fz/F/bzo993Is1W+Q7HjPzi7yg= github.com/dgraph-io/badger v1.6.1/go.mod h1:FRmFw3uxvcpa8zG3Rxs0th+hCLIuaQg8HlNV5bjgnuU= +github.com/dgraph-io/badger v1.6.2 h1:mNw0qs90GVgGGWylh0umH5iag1j6n/PeJtNvL6KY/x8= +github.com/dgraph-io/badger v1.6.2/go.mod h1:JW2yswe3V058sS0kZ2h/AXeDSqFjxnZcRrVH//y2UQE= github.com/dgraph-io/ristretto v0.0.2 h1:a5WaUrDa0qm0YrAAS1tUykT5El3kt62KNZZeMxQn3po= github.com/dgraph-io/ristretto v0.0.2/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= github.com/dgryski/go-farm v0.0.0-20190104051053-3adb47b1fb0f/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= @@ -324,6 +328,8 @@ github.com/ipfs/go-ds-badger v0.2.3 h1:J27YvAcpuA5IvZUbeBxOcQgqnYHUPxoygc6Qxxkod github.com/ipfs/go-ds-badger v0.2.3/go.mod h1:pEYw0rgg3FIrywKKnL+Snr+w/LjJZVMTBRn4FS6UHUk= github.com/ipfs/go-ds-badger v0.2.4 h1:UPGB0y7luFHk+mY/tUZrif/272M8o+hFsW+avLUeWrM= github.com/ipfs/go-ds-badger v0.2.4/go.mod h1:pEYw0rgg3FIrywKKnL+Snr+w/LjJZVMTBRn4FS6UHUk= +github.com/ipfs/go-ds-badger v0.2.5 h1:oKRP6xVdgunjioOvaW4Ue2N7rBI7h/sWNERHTguUmpE= +github.com/ipfs/go-ds-badger v0.2.5/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-leveldb v0.0.1/go.mod h1:feO8V3kubwsEF22n0YRQCffeb79OOYIykR4L04tMOYc= @@ -910,6 +916,7 @@ 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.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= +github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= 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/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= From cd1feb3af4e42a835870aca96243b55760ab5f04 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Fri, 25 Sep 2020 22:26:44 +0200 Subject: [PATCH 018/116] fix(gateway): correct breadcrumbs on dnslink site --- core/corehttp/gateway_handler.go | 11 ++++++++--- core/corehttp/gateway_indexPage.go | 19 +++++++++++++++++-- core/corehttp/gateway_test.go | 8 +++++--- core/corehttp/hostname.go | 21 ++++++++++++++------- 4 files changed, 44 insertions(+), 15 deletions(-) diff --git a/core/corehttp/gateway_handler.go b/core/corehttp/gateway_handler.go index b9e7f144b9d..cff82fef7f5 100644 --- a/core/corehttp/gateway_handler.go +++ b/core/corehttp/gateway_handler.go @@ -379,8 +379,9 @@ func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request hash := resolvedPath.Cid().String() - // Storage for gateway URL to be used when linking to other rootIDs. This - // will be blank unless subdomain resolution is being used for this request. + // 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. @@ -396,11 +397,15 @@ func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request Listing: dirListing, Size: size, Path: urlPath, - Breadcrumbs: breadcrumbs(urlPath), + Breadcrumbs: breadcrumbs(urlPath, gwURL), BackLink: backLink, Hash: hash, } + // TODO: remove logging below + // tplDataJSON, _ := json.MarshalIndent(tplData, "", " ") + // fmt.Println(string(tplDataJSON)) + err = listingTemplate.Execute(w, tplData) if err != nil { internalWebError(w, err) diff --git a/core/corehttp/gateway_indexPage.go b/core/corehttp/gateway_indexPage.go index c9a948708b9..5cbf33becfd 100644 --- a/core/corehttp/gateway_indexPage.go +++ b/core/corehttp/gateway_indexPage.go @@ -34,7 +34,7 @@ type breadcrumb struct { Path string } -func breadcrumbs(urlPath string) []breadcrumb { +func breadcrumbs(urlPath string, gwRootURL string) []breadcrumb { var ret []breadcrumb p, err := ipfspath.ParsePath(urlPath) @@ -42,8 +42,9 @@ func breadcrumbs(urlPath string) []breadcrumb { // No breadcrumbs, fallback to bare Path in template return ret } - segs := p.Segments() + ns := segs[0] + contentRoot := segs[1] for i, seg := range segs { if i == 0 { ret = append(ret, breadcrumb{Name: seg}) @@ -55,6 +56,20 @@ func breadcrumbs(urlPath string) []breadcrumb { } } + // Drop the /ipns/ prefix from breadcrumb Paths when directory listing + // on a DNSLink website (loaded due to Host header in HTTP request). + // Necessary because gwRootURL won't have a public gateway mounted. + if ns == "ipns" && (("//" + contentRoot) == gwRootURL) { + prefix := "/ipns/" + contentRoot + for i, crumb := range ret { + if strings.HasPrefix(crumb.Path, prefix) { + ret[i].Path = strings.Replace(crumb.Path, prefix, "", 1) + } + } + // Make contentRoot breadcrumb link to the website root + ret[1].Path = "/" + } + return ret } diff --git a/core/corehttp/gateway_test.go b/core/corehttp/gateway_test.go index f4d6d810d35..46bf76a5e69 100644 --- a/core/corehttp/gateway_test.go +++ b/core/corehttp/gateway_test.go @@ -391,6 +391,8 @@ func TestIPNSHostnameRedirect(t *testing.T) { } } +// Test directory listing on DNSLink website +// (scenario when Host header is the same as URL hostname) func TestIPNSHostnameBacklinks(t *testing.T) { ns := mockNamesys{} ts, api, ctx := newTestServerAndNode(t, ns) @@ -445,7 +447,7 @@ func TestIPNSHostnameBacklinks(t *testing.T) { s := string(body) t.Logf("body: %s\n", string(body)) - if !matchPathOrBreadcrumbs(s, "/ipns/example.net/foo? #<'") { + if !matchPathOrBreadcrumbs(s, "/ipns/example.net/foo? #<'") { t.Fatalf("expected a path in directory listing") } if !strings.Contains(s, "") { @@ -511,7 +513,7 @@ func TestIPNSHostnameBacklinks(t *testing.T) { s = string(body) t.Logf("body: %s\n", string(body)) - if !matchPathOrBreadcrumbs(s, "/ipns/example.net/foo? #<'/bar") { + if !matchPathOrBreadcrumbs(s, "/ipns/example.net/foo? #<'/bar") { t.Fatalf("expected a path in directory listing") } if !strings.Contains(s, "") { @@ -545,7 +547,7 @@ func TestIPNSHostnameBacklinks(t *testing.T) { s = string(body) t.Logf("body: %s\n", string(body)) - if !matchPathOrBreadcrumbs(s, "/ipns/example.net") { + if !matchPathOrBreadcrumbs(s, "/ipns/example.net") { t.Fatalf("expected a path in directory listing") } if !strings.Contains(s, "") { diff --git a/core/corehttp/hostname.go b/core/corehttp/hostname.go index 8b2666afb6c..4a531a4d371 100644 --- a/core/corehttp/hostname.go +++ b/core/corehttp/hostname.go @@ -129,7 +129,7 @@ func HostnameOption() ServeOption { if !gw.NoDNSLink && isDNSLinkRequest(r.Context(), coreAPI, host) { // rewrite path and handle as DNSLink r.URL.Path = "/ipns/" + stripPort(host) + r.URL.Path - childMux.ServeHTTP(w, r) + childMux.ServeHTTP(w, withHostnameContext(r, host)) return } @@ -143,10 +143,6 @@ func HostnameOption() ServeOption { if gw, hostname, ns, rootID, ok := knownSubdomainDetails(host, knownGateways); ok { // Looks like we're using a known gateway in subdomain mode. - // Add gateway hostname context for linking to other root ids. - // Example: localhost/ipfs/{cid} - ctx := context.WithValue(r.Context(), "gw-hostname", hostname) - // Assemble original path prefix. pathPrefix := "/" + ns + "/" + rootID @@ -201,7 +197,7 @@ func HostnameOption() ServeOption { r.URL.Path = pathPrefix + r.URL.Path // Serve path request - childMux.ServeHTTP(w, r.WithContext(ctx)) + childMux.ServeHTTP(w, withHostnameContext(r, hostname)) return } // We don't have a known gateway. Fallback on DNSLink lookup @@ -213,7 +209,7 @@ func HostnameOption() ServeOption { if !cfg.Gateway.NoDNSLink && isDNSLinkRequest(r.Context(), coreAPI, host) { // rewrite path and handle as DNSLink r.URL.Path = "/ipns/" + stripPort(host) + r.URL.Path - childMux.ServeHTTP(w, r) + childMux.ServeHTTP(w, withHostnameContext(r, host)) return } @@ -234,6 +230,17 @@ type wildcardHost struct { spec *config.GatewaySpec } +// Extends request context to include hostname of a canonical gateway root +// (subdomain root or dnslink fqdn) +func withHostnameContext(r *http.Request, hostname string) *http.Request { + // This is required for links on directory listing pages to work correctly + // 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 + ctx := context.WithValue(r.Context(), "gw-hostname", hostname) + return r.WithContext(ctx) +} + func prepareKnownGateways(publicGateways map[string]*config.GatewaySpec) gatewayHosts { var hosts gatewayHosts From 43b8a314f16a90bf5be7e85bb719a216fc425c14 Mon Sep 17 00:00:00 2001 From: Rafael Ramalho Date: Mon, 28 Sep 2020 18:10:23 +0100 Subject: [PATCH 019/116] chore: bump webui version --- core/corehttp/webui.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/corehttp/webui.go b/core/corehttp/webui.go index b0f4256c88f..c41be6300df 100644 --- a/core/corehttp/webui.go +++ b/core/corehttp/webui.go @@ -1,11 +1,12 @@ package corehttp // TODO: move to IPNS -const WebUIPath = "/ipfs/bafybeianwe4vy7sprht5sm3hshvxjeqhwcmvbzq73u55sdhqngmohkjgs4" // v2.11.1 +const WebUIPath = "/ipfs/bafybeifekmcbbi4nwyj4aasti6x3nuhyli464wfjjfdjg4xnz53lhyiedq" // v2.11.2 // this is a list of all past webUI paths. var WebUIPaths = []string{ WebUIPath, + "/ipfs/bafybeianwe4vy7sprht5sm3hshvxjeqhwcmvbzq73u55sdhqngmohkjgs4", "/ipfs/bafybeicitin4p7ggmyjaubqpi3xwnagrwarsy6hiihraafk5rcrxqxju6m", "/ipfs/bafybeihpetclqvwb4qnmumvcn7nh4pxrtugrlpw4jgjpqicdxsv7opdm6e", "/ipfs/bafybeibnnxd4etu4tq5fuhu3z5p4rfu3buabfkeyr3o3s4h6wtesvvw6mu", From c94bd768d2f755c8825674e72539d49a82503d12 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Mon, 28 Sep 2020 14:09:29 +0200 Subject: [PATCH 020/116] fix(gw): links in CID column on dir listing This switches go-ipfs to dir-index-html after https://github.com/ipfs/dir-index-html/pull/43 got merged to master --- assets/bindata.go | 4 ++-- assets/bindata_version_hash.go | 2 +- assets/dir-index-html | 2 +- core/corehttp/gateway_handler.go | 5 ++++- core/corehttp/gateway_indexPage.go | 23 +++++++++++++++++------ 5 files changed, 25 insertions(+), 11 deletions(-) diff --git a/assets/bindata.go b/assets/bindata.go index 514e5ae28d8..605b5945438 100644 --- a/assets/bindata.go +++ b/assets/bindata.go @@ -226,7 +226,7 @@ func initDocSecurityNotes() (*asset, error) { return a, nil } -var _dirIndexHtmlDirIndexHtml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\xbc\xc7\x0e\xc4\x5a\x92\xa6\xb7\xef\xa7\x28\x01\x5a\x48\x43\xcd\x90\x49\xcf\x9e\x9e\x01\xe8\xbd\xf7\xdc\x08\xf4\xde\x7b\x36\xfa\xdd\x85\xaa\xee\xe9\x2a\x40\xcb\xb9\x8b\xbb\x4a\x9e\x4c\xe4\x2e\xe2\x8b\xff\x8f\x08\x9e\x7f\xf9\x3f\x38\x93\xf5\x62\x8b\xff\x4b\x73\x8c\xc3\xff\xfc\xa7\x7f\xfd\xd7\xbf\xfc\x9f\xdb\x3c\x1f\x7f\xf9\xe7\xff\xf1\x97\xff\xf6\x97\x7f\xfb\xb7\x7f\xfa\x97\x7f\xff\xfe\x5f\x9a\x32\x2d\xfe\xe7\x3f\xfd\xcb\x7e\xbc\x43\xf9\x3f\xff\x09\xfc\x2f\x7f\x71\xe7\x73\xcb\xcb\xbf\xfc\xd7\xbf\x54\xed\x50\xb6\xf9\x3c\xed\xff\x6d\xde\xea\xbf\xfc\x17\xf0\xbf\xb5\x4b\xb5\xff\xd7\xff\x37\x1b\xd2\xa9\xff\xcb\xbf\x66\x69\xde\xd7\xdb\x7c\x4e\xc5\x7f\x6d\xc7\xb4\x2e\xff\xf9\xdc\x86\xff\xab\x48\x8f\xf4\x9f\xff\x76\x04\x97\xa9\xfe\xef\x59\xba\x97\x38\xfa\xff\xb4\x01\x63\x3a\x37\xa4\x8a\xf5\x4c\xd3\x34\x6d\xb8\x7e\xc3\xfb\x35\x4d\xd3\xcc\x5f\x8f\xb4\xcd\xd2\xf1\x5f\x3f\x2b\x12\xa4\x9a\xbf\x3e\x88\x91\x23\x84\x92\xe3\x65\x70\x02\x15\xb0\xf0\x26\x36\xc3\x24\x22\xd5\x26\x2e\xa3\x64\xa1\x30\x25\x81\x32\xc4\xa1\x83\xe5\xf9\x30\x58\x7f\xfd\x43\xc8\x28\x0e\x2f\xf8\xa5\xb1\xf2\x7e\xf7\xd3\x1e\x9e\xb6\xa7\xe2\xa7\x07\x34\x3a\xbc\x32\x1f\x3e\xb8\x2f\xab\xbc\xe8\xf3\x8f\xb8\x67\x2c\x72\x68\xd5\xad\x80\x8d\x07\xd6\x44\x30\xb0\xd3\x99\xad\x4f\xc4\xdc\x35\x68\xa3\x8d\x6d\x81\x5a\xa3\x6a\xd8\x94\x9c\xcc\x7e\x9d\x62\x15\x62\xba\xf8\x9e\x9f\x4e\x74\x5f\x71\x05\xa7\x83\x71\x75\x3c\x25\x40\x45\x51\x69\x4b\x04\x07\x76\x50\x2a\x75\x4e\x27\x2a\x69\x77\x29\x23\x6b\x18\x3f\x32\x6e\x71\xf3\x5e\xbc\x50\xd5\xe4\xd3\xf1\x98\x28\xca\xe6\x26\xf3\x59\x34\x31\x56\xfc\x7b\x4a\x77\x45\x4c\x87\xdd\xa3\x5d\x3e\xbd\xb7\xf9\xc8\x43\xf5\x98\xac\x11\xa7\x5a\x50\x67\x78\x1e\x65\xbd\x57\x34\x4a\xb4\xc2\xae\x3c\x18\x3a\x0b\x3d\xf2\xda\x48\xf9\xc7\x65\x2d\x69\x06\xdf\xa2\xb9\x7e\x0a\x85\x65\xe6\x54\x63\x5b\x6b\xd2\xda\xfd\xf8\xdc\x4a\xa6\xbb\x22\xea\x8c\x93\xb7\x38\x70\x5e\xbe\x9d\xce\xad\xc3\x3b\x8f\x91\x5e\x99\x58\xd6\x60\x13\xec\x95\xcf\x0e\xdc\xe3\xc7\x84\xba\x7e\x86\x43\x2b\x06\xfb\x7b\xbc\xf8\x91\xed\x06\xd4\x47\xc7\x1f\x46\xc1\xe6\x91\x35\x34\xc3\xdf\xb4\x32\xb0\x17\xf6\x3f\x10\x39\x6a\x25\x80\xee\x34\xb8\x7a\x41\xe6\xcb\x24\x93\x56\x94\x1f\x5e\xf5\xa3\x47\x3e\x32\x1f\xbc\x9e\xf8\x40\x39\x43\xe6\x1b\x7b\x47\x61\x1c\x2b\x16\x13\x86\xdb\x83\xd4\x1c\x16\xb7\x0e\x14\x1e\x7e\x83\x94\x2e\x41\xa8\x7f\x40\x24\xfd\x18\xc7\x84\x82\x3d\xd3\x85\x84\x47\x58\xce\x4d\xd4\xbb\x4c\xaa\x58\x0e\x6a\x80\x4b\xf0\x8b\x68\x28\x91\x0b\xcc\x3b\xb1\x6e\xd0\x9a\x1f\xf5\x04\x2b\xba\xbe\x69\x2d\xe3\xe8\xa8\x22\xb8\xc2\xee\xff\x16\x28\xae\x1f\x98\x8e\x8a\xb1\xb1\x2c\xff\x8f\xff\xfb\xbf\xff\x43\x00\x6e\xe5\x52\xa6\xc7\x3f\x4f\xf3\x7f\x3c\xfd\xe3\x6f\x7b\xfb\x95\xff\x9c\xcf\xd3\x91\xb6\xd3\xbf\xfd\x47\x08\x2f\x69\x5d\xfe\xb9\x22\x78\x6c\xfe\x23\x82\x97\xdd\xff\x8e\x0b\xfa\xd1\xb1\x55\x15\x8d\xf9\x82\x91\x97\x90\x50\x10\xfc\x82\x99\x5d\x07\x1a\xfe\xec\xd5\xaf\x6f\x9d\xe7\xb7\x90\xa1\xb5\x0b\x15\x15\xae\xe2\xb9\xd1\xe4\xa5\x5d\xf0\xd6\x80\xf5\xf8\x87\x6e\x5b\x57\x86\x6d\x5e\x55\x54\xde\x0d\x04\x81\x09\x67\x08\xf5\x78\xd7\xf9\xaa\x17\xce\x09\x2d\x06\x7b\xed\xa8\xe0\x82\x04\x30\x0c\xfb\x2e\x9d\x32\x52\xf9\x37\x6f\x29\xb6\x5f\xd9\x4b\x99\x53\xe6\xf3\xcc\x53\x73\x83\xac\xb6\x61\x17\xd9\xa5\xf6\xfe\x28\x30\xfa\x11\x3b\x7f\xe4\x56\x0c\x6f\x87\xe4\x52\x38\x28\x9d\x90\x73\x45\x91\xf6\x01\xb9\xff\xe9\x24\xf1\xb9\xcd\x2e\xc3\x14\xb7\x48\x6c\x7c\xa0\x3c\xce\xcc\x0f\x2a\x27\x9f\x37\x65\xdc\x43\x04\x04\x2a\x76\x8d\xe9\x56\x77\xcd\x43\x12\x8c\x23\xa4\x4a\x35\x10\x49\x23\xad\x24\x06\x59\xe7\xdd\x44\x8d\xc7\x23\xfd\xde\x20\x53\x97\xb9\x64\x88\xa2\xd2\x5d\x95\xdd\xc8\xd5\x58\xc9\x02\x47\x47\xca\xd2\x9d\x67\xdd\x12\x45\x27\x0b\x81\x8c\x5a\xd0\x32\xe4\x47\xad\xd8\xd0\x33\x09\x25\x56\x9a\x26\x04\x9b\x37\xbf\xc0\x41\xdf\xb8\xec\xc4\x92\xa1\xc9\x16\x6b\x7d\x4f\x9f\xf0\xa0\xa0\xfc\x2e\xcb\xed\x04\x06\x10\xc5\xd1\x5e\xe6\x6b\x42\xff\x16\x06\x25\xcb\x9e\x9e\x6e\x0a\x44\xc5\xe4\x41\x34\x08\x35\x40\x71\xf6\x6e\xbe\x8b\xd0\xdc\x90\xb0\x6b\xb0\xaa\xee\xa0\xe5\x78\x21\xf3\x70\xb3\xcf\xe3\xd9\x58\x4c\x9f\x0b\x24\xd8\xa3\xc0\xd3\x05\x77\x3d\x52\x1e\xa8\x07\xaa\x68\x52\xff\xe1\xe1\x23\x4a\x5a\x81\x98\xe2\xb6\x4d\x0f\x05\xb9\xb0\x9d\x74\xc0\xdf\x6b\xb2\x86\x66\x9e\x77\xd7\xf3\x5a\xeb\x65\x23\x4b\x15\x8a\xb4\xc8\xa9\x48\xbb\x3b\xd7\xcf\x82\x2d\x2a\xf6\x2d\x85\x7a\x2e\x85\x4a\x6c\x8e\x7e\xf7\x33\xbb\xcb\x9e\x8f\xf3\x3d\x0e\x6c\x92\x74\x8d\x17\x7b\xf6\x7d\x70\xdb\x47\x48\xb4\xbb\x7b\x9f\x2e\xe0\xfd\x51\x32\x17\xb4\xdd\x26\x39\x6a\x90\xdc\xa4\xef\xb3\xcd\xcf\x4d\x85\xe6\xb1\x37\x1a\x8f\x6b\x5b\xb7\xa5\xb9\x63\xfd\xa1\x9e\x58\x9a\xbe\x54\x81\x99\xa3\x28\x95\x2a\x7a\x73\xd9\x84\xe3\xa1\xfa\x0d\x95\x5a\x90\xd5\xf1\xf2\x05\xd5\x44\x75\xdf\x90\x7b\x38\x45\x81\xc6\xe4\x0e\xce\x0f\x4e\x05\x54\x08\x04\xa6\x55\x17\x4f\x0e\x79\x2c\xbc\x97\xb6\x6d\x06\xc9\x12\x83\x1c\xa8\x83\xc0\x64\xa1\x81\x14\xdd\x2f\x02\x75\x9f\x9b\xdd\xb7\x56\xa7\x9e\xfa\x14\x3a\xe2\xba\xae\xe3\x85\x95\x7a\x55\xf4\x76\x49\xc6\x0c\x53\x9f\x3b\x06\x6d\x3d\x99\x65\xcb\xe5\x8a\x30\x84\x96\xf9\xca\x3e\xd2\x5f\xeb\xb3\xe3\xec\xb5\xcc\x58\xf0\x5b\x0b\x3b\x75\x51\xa8\x42\x73\x2a\xf3\x9a\x81\x69\x05\xbe\x37\x58\x20\x9f\x67\xe8\xb8\xdf\xa7\x66\xd5\xee\x38\x9c\xfa\x75\x51\xd0\xd9\xf4\x01\x5b\x74\x5a\x31\x10\x4c\x5f\x77\x50\x20\xfb\xd1\x74\x36\x6a\x1d\xbb\x55\x4c\xeb\xd4\x7f\x28\x21\xd2\x34\xff\x73\xf1\x61\xfa\x4f\x3e\x40\x7e\xff\xb3\x78\x88\x8f\xab\x63\x3b\x83\xe1\xa2\xfd\xbe\x09\x78\x6b\x66\xf2\x9d\x9f\x35\x47\x61\x62\xe8\xa7\x5b\x52\xc7\xee\x48\x7e\xcd\x75\xee\x81\xe8\xaa\x28\x06\x66\x5c\x52\x33\xcf\x4d\x6e\x4e\xd6\x8d\xc6\xbc\x28\xf7\x6c\x03\xcc\x9a\xc8\xa8\x23\x92\x10\x53\x82\x14\x63\x09\x5f\x9d\xd9\x78\x79\xd7\x2a\xca\x95\x7c\xd6\x65\xea\x24\x28\x89\xf0\x8a\xc0\x18\xb7\x21\xbd\xb6\x10\xf1\xaf\xcd\x16\xf9\xe9\x76\x54\x6d\x6c\x26\xa9\xae\x00\xdf\x09\x15\x0b\x32\x28\xeb\xca\xb9\xc2\x92\x21\x17\xdf\xdd\xfa\xa5\xd8\x6f\x6c\x2b\x93\x7b\xb3\xeb\xe3\xc9\xf1\x63\xb3\x8d\x9e\x3d\x4e\xf6\x1a\x7d\x16\xa3\xa4\x4d\xd0\xd8\x6d\xcf\xad\x02\x92\x5f\x54\x9e\xec\xaa\x10\x66\x07\xec\x2a\xd2\xd9\xb9\x41\x8f\x35\xf9\xf4\xa2\x4d\xfc\xc6\xb8\xec\x72\x9a\x41\xa9\x6b\x19\xcb\xf3\x53\xf2\x7c\x80\x80\xc2\xef\x70\x55\xa6\xaf\x4a\x62\xad\x1a\x31\x80\x93\xbe\xd0\xab\xa6\x18\xf3\xc9\xd9\xb1\xe2\xbf\xd3\x02\xeb\x72\x5a\xc6\x72\x6d\x78\xbd\x3e\x8b\xf2\x07\x29\xf7\x08\x70\xa7\x2f\xbf\x7e\xe1\x0d\xeb\x09\x67\xef\xac\x57\x11\x58\x38\xe5\x36\x32\x25\xff\x48\xbb\xd7\x86\x46\x8b\x00\x83\xbe\x7c\xce\xcd\xf5\x2d\xf9\x3d\xac\x4c\x7b\xe3\x97\x95\x57\x35\xb2\xc3\xd9\xb7\x16\x66\x08\x8d\x52\xdf\x7d\x57\x3a\x5e\xa9\xb9\x4d\x61\xce\x81\xb2\x4e\x74\x7d\xf7\x35\x4b\x27\x38\xe0\x17\x1a\x4b\x1d\x77\x67\x27\xe4\x52\x7c\xed\x2c\xf4\x09\x23\xc5\xc8\x8a\x33\xc8\x80\x16\x0a\xcf\xf3\x96\xc9\x96\x1c\x9a\xc7\x81\x44\x44\x7b\xf5\xc3\x04\x40\x90\x47\x96\x20\x30\xd9\xa0\x15\x46\x71\xfb\x60\x0e\x67\xc8\x8e\xa9\x78\xad\x5b\x07\x4d\x92\xcf\x49\x45\xa6\x2f\x6e\x15\xc9\x84\x47\xd4\x9c\xc4\xaf\x18\xc4\x19\xe1\x07\x7d\x28\x56\x3c\x76\xff\x91\x28\x3b\xee\x55\x99\xe5\x84\x53\x7b\x54\x7a\xfe\xc4\xe4\x2e\xbc\x95\x71\x76\x58\xc8\xb4\x21\xca\x5a\xab\xe0\x59\x9d\x95\xd2\xa2\x03\xe9\x94\x8b\x12\x43\x58\xcb\x82\x95\xaf\xc9\xc9\x5d\xd4\x5f\x9c\x99\x00\x1a\x16\xfb\xfc\xf1\x26\xcd\xa5\xa4\x6e\x5f\x68\xa7\x6b\x19\x13\xc2\x50\x0f\xd8\xf1\x46\x06\x6d\xd4\x64\xc6\x27\x72\xb5\x50\x73\xfd\x49\x4c\xaf\x0e\x41\x4c\xdb\xcc\xe6\x0f\x5f\xcb\x40\x91\xed\xb6\x15\x1a\x8f\x76\xd3\xef\xb5\x21\x2b\x3d\xd5\xa6\x5a\x63\xa5\x01\x95\x81\xfe\x08\x9c\x8a\xcb\x16\xdf\xcb\x65\x62\x62\x3b\x6e\x7f\x75\x33\x30\xa1\x8a\xf1\x9c\x99\xe8\xbb\x3b\xdb\x01\x09\xbb\x98\x5c\xdc\xf5\xa2\x4e\x1b\x1c\xdc\x13\xe5\xe3\xef\x55\xd3\xb3\x05\x00\x53\x6f\x7d\x32\x24\x19\x0e\x84\x10\x82\x33\x7e\x78\x04\x58\xe7\xd1\x4a\xd7\xe2\x45\x34\xcd\xf3\xd3\x42\xa6\xdd\x4a\x29\x98\x08\x2a\xb6\x70\xb6\xb1\x91\xa9\xcb\xc0\x52\x18\xaa\x70\x15\x57\x0f\x91\x90\x64\x10\xe5\x46\x94\xe1\x16\xf6\x4d\xd0\x07\xef\xfe\xa6\xe9\x71\x4e\x87\xfc\x19\x0c\xfa\xf7\xb7\xec\xe4\x07\xc1\xeb\xdd\xd3\x1e\x59\xf6\x7f\x8b\x19\xed\x9f\x0b\x19\x3d\xf6\x77\x49\x01\xfd\x2e\x7e\xe0\x7d\xcb\xb3\xbe\x64\x65\x68\x3b\x75\x05\xbb\x55\x62\x7f\x1c\xd4\xb8\x99\x3d\x01\xfd\x69\x88\x97\x9d\xa0\x0d\x02\xf4\xb5\x47\x08\xb3\x80\xb5\xb5\x9f\xa1\xb6\xad\xef\x6a\x13\x9e\xff\xe8\x07\x7d\x09\xbf\x23\x16\xe7\xe8\x36\x6e\xe2\xbe\x88\xef\x8e\xeb\x43\x8d\x10\xed\x46\x08\x0a\x23\xb0\x05\xfb\x08\xc2\x84\x7e\x73\x13\x02\x20\x17\x34\xe4\xd7\x11\x69\xac\x36\xd5\x20\x16\x22\x95\xec\xe2\xad\x19\x6f\x51\x55\x75\x50\x6d\x3f\x2a\x96\xae\x9d\x4f\x81\xe4\x04\xa7\x67\x2a\xe6\x0c\x73\x0f\x5b\x05\x8a\xf7\xbb\x92\xef\xbd\xc1\x5a\x1d\x46\xbd\x23\xe4\xb7\x16\x74\xe0\xb9\x8c\x3c\x9d\x16\x14\x3c\xb0\x82\x9e\xc7\x48\x62\x5e\xd8\xf7\x19\xd3\x84\x75\x7a\x00\x19\x0a\xcc\xad\x0c\xb7\x7c\xed\x9c\xa5\x07\x0a\x75\xa8\x44\xc4\x6b\xf1\xcd\x87\x43\xee\x84\x56\xc2\xf3\x48\xd6\xd8\x8f\xc7\x75\x71\x6b\xcc\xd4\x6b\x09\x89\x6d\x33\xd3\x30\x2a\x84\xc0\x73\x18\x96\xed\x75\x10\xa9\xac\x7b\x95\x5f\xdb\x90\x71\xc5\x00\x75\x90\xcb\x26\x76\xb9\x71\x73\x2f\x11\xbc\x45\x7a\x10\x1a\xfe\x61\x0c\xb6\x0f\x67\x10\x83\x61\xa8\xd7\x04\x40\x7b\x0c\x38\xe4\xda\xae\x2e\xde\x3c\x49\x1f\x07\x98\xba\xc0\x9f\xde\x47\xb6\x7d\x7f\x50\xea\x7d\x50\xb1\x92\x30\x08\x99\x2f\x4c\x31\xdb\x74\xa2\x14\xda\xc5\x8a\xcc\x5b\xcd\x16\x83\x47\x45\x4f\x41\x4b\xfc\xe2\x51\x8d\xe4\x20\x97\x86\x37\xbd\xd5\x10\xc5\xa5\x22\x36\xb0\xbb\x2f\x18\xd0\x92\xf7\x09\x3d\x77\x05\x4b\x8e\x68\x7a\x32\x6b\x4a\x6b\xa7\x5b\x97\x1f\x11\x30\x3f\xe7\xe0\x5c\x3f\x34\xed\xcb\x4f\x19\x4d\xf0\x3f\x85\xd1\x15\x98\xbb\x47\xab\x2e\x7e\xca\x3d\x42\xe1\xec\xd6\x4a\xd5\x71\xd7\xe6\xa9\xcf\x71\xd3\xf2\xcb\xf7\xb4\x69\x63\x8d\x0f\x82\x49\x51\x63\xe7\x7c\x73\x83\x6f\xe8\xd3\x9d\x68\x21\xb4\xbb\xa7\x7f\xd2\x6c\xdc\xdc\xb6\x73\x0b\x97\xf2\x9c\x0b\xdb\xf1\xb1\xef\xe7\xb9\xd9\xcf\xa9\x3a\x16\xe6\x90\x4c\xf1\xcf\xeb\x6b\x3a\x8f\xe8\xe6\x69\xcc\x5b\xdb\xb9\x5d\x9a\x0d\xe4\x44\x4d\x4c\xf1\xb8\x2a\x60\x25\x5c\xa6\xa6\xaa\x93\x0b\xa4\x96\x6b\xd7\xa7\x3d\x41\xe9\xc1\x26\x28\x2f\xf1\x30\xf5\xdb\x85\xa2\xdb\x46\xe8\x8f\x01\x85\x6d\x50\x6b\xd2\x86\x09\x19\xee\xd2\x2b\x98\x93\x4d\xa8\x6f\x0e\x5d\x83\x76\xa1\xf9\x57\x1f\xa6\x54\xa0\xb7\x2f\xed\x40\x0e\xe2\x5a\x3d\x1a\x14\x5a\xb0\x5f\x15\xde\xc8\x6a\xd2\x75\x27\x59\xd0\xc1\xfe\xe9\xa9\xab\x61\x87\x0f\xfe\xfa\x95\xee\x75\xb6\x81\x8f\x58\x06\x08\xa0\x6f\x08\x28\xef\xac\x6c\x43\x33\x3e\xc1\x7e\x5d\xb2\x91\x9e\x32\x31\x94\xa5\x44\xcb\x87\x04\x28\xcd\xd0\x96\x69\x07\xca\x04\xdb\x38\x24\xfe\xb1\xa9\x5f\x55\x7f\xae\xe4\x9f\xff\x53\x2f\xf4\x3e\x75\xac\xfc\x8f\xf7\xa3\x64\x4c\x16\x1e\x49\x3d\x46\xcb\x14\xc1\xf2\x0e\xc1\x77\x0e\x97\x3d\x9a\x8d\xf0\xd9\x57\x55\x05\x05\xa4\xe8\x09\x99\x6b\x9c\xae\xc1\x39\xaa\x66\xbf\x23\xe6\x9a\x4a\x77\x96\x89\x55\x0f\xf7\x65\x4b\x4a\xc3\x63\x59\x09\xc3\x87\xd3\x44\xc5\x3e\xec\x4e\xa8\xe7\xd1\x17\xfd\x4e\xb8\xb3\xbc\x3f\x6a\xd9\x36\x04\x4e\x5a\x13\x24\x58\x23\xe5\x1e\xc4\xd4\x0e\xbc\x32\x3b\x66\x15\x6b\x30\x55\x1d\x56\x96\xa7\x85\x04\xd4\xaf\x52\x25\xa2\x3a\x8b\x29\x10\x30\x72\xe2\x7f\x78\x39\x00\xe0\xeb\xc3\x23\x23\xb8\x61\xa2\x2e\xa1\xa2\x06\x39\x64\xd6\x3e\x33\x43\xb0\x8a\x1a\xdc\xe8\xe3\x33\x81\xe9\x0f\x10\x16\x27\x25\xfb\x91\x50\xb6\x26\x0d\x2e\xd3\xef\x91\xca\x38\x3d\xeb\x80\x2b\xbe\x25\x5b\xa8\xdf\x2a\x0e\xb4\x2a\x7a\x0f\x59\xb0\x3f\x0a\x0c\x97\xa7\xe9\xa6\xfd\xe9\x40\xc7\xb9\x7b\x12\x6b\x44\x85\xa5\x8a\x9f\x89\x57\x53\x19\xd2\xe7\xfc\x1d\x5c\xec\xba\x5a\x49\x99\x1e\xee\x9e\x11\x03\xe7\xf9\x43\x20\x09\x75\x9e\xfd\xcd\xdd\xd5\xb0\xff\x6a\xe8\x49\xe4\x18\xa4\x0b\x50\x9c\xde\x03\x8c\x82\x2a\x7b\xe3\xcd\xe5\x1c\x9e\xb4\xf8\x47\x62\x70\x90\x64\x70\xfb\x4c\x1f\xf9\x76\x18\x41\x3f\xa0\x56\xa6\x5b\xfd\x01\x34\xf6\xdd\xc9\xae\x12\x15\xde\x6f\x7b\x38\x5c\x12\x93\x83\x5d\xbb\xa2\x66\xee\x08\x56\xfb\x9e\x17\x96\x6e\x63\x1c\x17\x5c\x70\x1e\x91\x8c\xc0\xd8\xc0\x85\xf5\xc1\x27\x68\x05\x0e\x5b\x85\x61\x93\x2e\x81\x0b\xe5\x74\x7a\x4e\x49\x84\x5b\xa0\x1d\xc2\x67\x99\x2e\x45\x2a\xa3\x7a\x62\x38\xe6\x67\xf6\x70\xd8\x8e\x2a\x47\xc4\x5b\x8a\x1d\x17\x16\x65\x2f\x45\x96\x79\x5c\x48\xac\x63\x91\xf9\xd6\x1b\x87\x17\x12\xad\xa7\x78\xa2\x65\x98\x75\x33\x37\xb3\x1a\x7e\x11\xe8\x94\x87\x3f\x93\x4b\x7d\x7a\x08\xc3\x9b\x9b\x5d\x8c\x6b\x4a\x71\xcd\xc2\x25\xe0\x41\x88\x1d\x57\x36\xa6\xd6\x9e\x7f\x65\x83\xc9\xcb\x0c\x3e\x69\xce\x31\x6c\x32\x73\x43\x3a\x08\x3e\x59\x50\xe7\x91\xb5\xdb\x11\x80\x86\xd3\x45\x5f\x35\x1e\x76\x69\x70\xde\x64\x26\xf8\xdd\xe5\x59\x18\x51\xb1\x8b\xde\xa3\x06\x94\x28\xf8\x4b\xfa\xd3\xb9\x9e\x92\x71\xb1\x89\x7f\xe0\x77\x81\xd5\xb5\x79\xac\x39\xc0\xbc\xd8\x05\x49\xf6\x28\xe8\xe5\x1d\x74\x6a\x4f\x6c\x55\x75\xed\xef\x2d\x1d\x6f\x2f\x9d\x00\xb6\x67\xfa\x93\xe3\x98\xec\xc6\x12\xe3\x0c\xaa\x92\xa1\xc2\x9e\x7d\xb9\xa3\x0d\xf1\x2d\x2c\x2a\xd0\x09\x2b\xb9\xa9\x05\xa4\x5b\x66\x31\xe2\xad\xc8\x6e\xf0\x80\x5e\x4f\x59\x9d\xa3\xf0\x29\x7f\xab\x14\xd6\xd7\x17\x57\x91\xeb\x2c\xfc\xf6\xb8\xc4\x7e\x4c\x1e\xb4\xd2\xa7\x49\xe5\xca\x3a\x6b\x93\xfc\xe2\xe8\x77\x08\xb7\x51\x25\xcc\xe3\x52\x26\x62\x84\x3d\x9d\x4b\xab\x83\x43\x78\x0f\x4e\x20\x92\xcf\x2a\x3d\x07\x60\x4c\x5c\x36\x68\xc6\x6c\x52\x5e\xc3\x36\x5e\x48\x0e\x89\xbb\xd0\x40\xf8\x89\x80\x15\xaa\xea\x34\x73\xb9\x61\xc5\x49\x63\xa6\xc2\x7f\xb3\x1e\x8c\xe2\xf8\x18\xbf\xf5\x4a\x5d\xd7\xff\xe3\x7f\xcf\x7b\x5c\x7f\x32\x21\x31\xfe\xfe\x2e\x24\xc8\xe3\x84\x20\xda\xb7\xa2\x24\x37\xa0\xe9\xf3\x96\x15\x56\x6d\x64\xa1\xef\x5e\xa6\xa7\x50\x5a\xd9\xb9\x2c\x1f\x26\x03\x68\x1b\xa0\x99\x84\xa4\xe1\x1d\xa0\xe5\xbe\x18\x61\x1c\xb7\x7d\x45\x16\x42\x95\xe9\xa5\xfa\xa7\x2e\x8e\xd4\x62\xf3\xa8\x88\x7d\xa6\x20\x99\x28\x75\x00\xaa\xff\x78\x7b\xf3\x2e\xf7\x15\x2d\xeb\x2c\xcb\x32\x07\x80\x1f\x5f\xdb\xcc\x23\x2d\x00\x48\x8d\xd9\x7b\x6e\xad\x93\x14\x4f\xa7\xa4\xad\xca\x70\x48\x08\x9c\x3f\x60\xa1\x52\x12\xc3\xc7\xf4\x01\x6a\xce\x24\xcb\xcc\x03\x42\x0f\x86\xf8\xaf\xa5\x8c\xa4\x05\xf3\x6d\x4d\x8b\x6b\x82\x75\x9b\xa1\xc5\x6a\x61\xcd\x65\x35\xb6\x13\xa6\x10\xe2\x7a\x2c\x79\x89\x71\x73\xea\xf2\xfc\x41\xbc\x3b\xef\x29\x9d\x69\x5d\x1f\x9a\xf2\x4a\x6a\xb7\x48\x18\x93\x08\xd1\x0b\xea\x5e\x59\xff\x6e\xf9\xc0\x00\xbf\xd4\xae\xa4\x03\xba\xaa\x8c\x29\xb1\xd3\x7e\x4f\x2b\xa8\x97\x01\x4b\xa6\xdf\xef\xcd\x34\x14\x6c\xc1\xa1\x97\x59\xf3\xc6\xa6\xd6\x76\x44\xdb\x6d\xe6\x76\x95\x71\x66\x46\x91\x10\x3e\x33\x72\x42\x1a\xe7\xd0\x12\x8f\xa8\xbd\x77\xea\xf1\xba\x67\x23\xaa\xa6\xcd\x67\xa1\xa7\xa7\x91\x12\xee\x66\x7f\x60\x2a\xff\xf8\xa0\x55\xe6\xe1\x04\xed\x46\x75\x74\x29\xf9\xf9\x11\x24\x6e\x3f\xdf\x95\xf9\x09\x13\xac\x50\x7a\x01\xf0\xf6\xe6\xbe\xdf\x6c\x73\x85\x2f\x26\x95\x12\xc6\x40\x9b\x31\xa6\x94\xbb\xda\x50\x7a\x02\x8f\xb2\xe5\x19\x14\x4b\x12\xee\xe6\x5a\xbd\x99\xf9\xc7\x83\x0c\x60\x8f\x39\xf6\xf4\xfb\x7e\x19\x34\x79\x88\x2c\x14\x8c\xf8\xa8\x98\x01\xc7\x6f\x8a\x86\x71\xdd\xca\xbf\x8f\xc0\xf3\x45\x52\x97\x25\x95\xb2\x83\x55\x26\x38\xf0\x8c\xf1\x6b\x83\x97\x7b\x64\xad\xad\xff\x00\xaf\xa7\xea\x9b\x76\x42\x9b\x0a\x9f\x65\xc9\xa2\xa4\x31\xa6\xe5\x06\xde\x14\xa5\x31\x29\x69\x71\x0d\x1d\x64\x87\x0c\x5f\x36\xd7\xf0\xdd\x4b\x5a\x3a\xec\xc2\x9a\x1e\x97\xa7\x9f\x30\xa0\x5f\xbd\x74\x54\xf1\xb0\x67\xef\x91\x77\x46\x8d\xd3\xae\x8e\x81\x74\x8d\x6a\xfb\x30\xb2\x34\xe1\x9c\xbf\xd8\x4c\x17\x44\x23\xa5\xd8\xc0\x39\xa9\xc8\x5c\xb0\xc0\xd8\xd2\x0b\x98\xa9\x60\x3e\x92\x10\x58\x46\x8b\x7b\xc3\x7b\xe5\x8e\xb1\xcb\x71\x92\xf9\xdd\x8d\xb1\x21\xde\xd4\x1f\xe0\xcf\x61\xee\xcd\x9a\xde\xf1\x12\xfd\xca\x36\xcc\xb0\x8c\xfb\x80\x46\xd0\x00\x89\xdf\x6c\xeb\xc8\xaf\x4c\x99\xb9\x48\xf8\x36\x85\x56\x43\xdf\x01\x9e\x35\x9d\xca\xfd\xb0\xbb\xa2\x26\xb1\x5a\x8a\x7f\x9c\x2e\x36\x09\x2c\x75\xaf\xb8\x4f\x8b\x60\xad\x86\x34\xc5\x70\x35\x4a\x17\xe2\x60\xae\xfe\x8e\x71\xe6\x98\xfb\xe7\xda\xb0\x63\xd2\x31\xb5\x4a\xed\x5c\x5d\xc3\xe3\xe6\xd8\xb3\xab\xea\xba\x4e\x31\x52\xb4\x0e\x4f\x35\x68\x84\x15\xe0\xf2\xd5\xc4\x30\xe9\x68\x7b\xed\xdb\x4d\x73\x25\x15\xd6\x20\x6b\x2b\xb5\x40\xff\xb1\x9c\xc8\xc6\xe5\x4f\xc6\x89\xe4\xef\x3d\x0a\xe0\xb7\xf9\x03\x1f\x83\x3f\xe4\xa2\xe2\x00\xba\x56\xf8\x3e\x0e\x19\x63\x8b\x45\xa3\x52\x5e\x64\x12\x9f\xbb\xa0\xa2\xc2\x71\x52\xc6\x27\x60\xde\x20\xdf\x06\x9d\xf3\xe4\x20\xbe\x0e\x38\x3a\xd9\x76\x55\x40\x69\xe7\x97\xe2\xac\xa9\x86\xd8\x1a\x5d\x51\x99\xc3\x84\x75\x06\x65\x91\x22\x59\x9d\x0b\x78\x49\x82\x6f\x89\x81\x05\x31\xb5\x7a\xd2\xd4\xfc\x33\xa9\x54\x95\x79\xdb\x88\x2d\x19\x23\xea\x09\xd7\xd7\xec\xbb\x02\xc1\xdb\x78\x7e\xea\xe1\xfc\x0c\x27\x92\x52\x5a\x56\x18\x29\x91\xd3\x94\x1f\xc2\xfc\xde\x67\xd4\x41\xbb\xc8\x8f\xc8\x77\xd9\xfa\x08\x50\xeb\x45\xd9\x2b\x46\xf2\xfe\x45\xcb\xdf\x83\x71\x83\xc6\xa6\x62\x96\x7d\x5d\xc4\xe5\xf3\xb9\x8b\x98\x69\x97\x98\x64\x39\x2e\x6b\x5b\x2a\x6a\x2d\x3b\xaf\x83\x91\x84\x86\x57\xe3\xa2\xd3\x5c\x9e\x88\x72\x4b\xa2\xe8\xb4\xbe\xd6\xec\xfa\xac\x26\x2e\x2a\x43\xe2\xc1\xcb\x0c\x35\xd6\xbe\xa6\x88\x34\x04\x50\x9c\xc5\x2c\x8c\x47\xec\x55\x75\x55\xbf\x10\xd4\x6a\xdc\xac\x95\xb3\xba\x49\x16\x62\x1d\x91\x8f\xc2\xf4\xf3\xef\xb6\x7d\x05\xbb\xa3\xc9\x6c\xef\x02\xb5\x4b\x95\x6f\xbe\x74\x0e\xb4\xb1\xfa\x79\x95\x46\x84\xf3\xeb\x2d\xa3\x12\xce\xe9\x93\xe6\x6c\x43\x64\x46\xe6\xd2\x52\xf1\xf4\x04\x27\xe5\xaa\x06\xf9\x0d\x8c\x17\xb6\xd4\x72\x8e\x5d\xa6\x42\x0c\xaa\xd8\xe7\x80\x5c\xa6\xbd\xe8\xa4\x52\xec\xbd\xa9\x6d\x05\x7b\x71\x39\xd7\xd1\x7b\x77\xd4\x98\x27\xf7\x73\xab\x6a\xe9\xdc\xeb\x86\x03\xe7\x53\x92\xad\x06\xad\xbf\xf9\x2a\x12\x51\x26\xa9\x0e\x5c\xe9\xdf\x6d\x82\xc5\xfe\xb8\xf7\x09\x31\x2d\xa3\xec\xc6\x7e\xc1\xda\x4d\x2b\xb4\xc2\xca\xd8\xf9\xc0\x75\x14\x67\xab\x51\x1e\xf9\x87\x59\xb3\xe9\xc8\xbf\x9c\x73\xa1\x89\xa4\x1f\x31\x24\x68\xe0\xbb\xf8\x98\x51\x13\x38\x19\xf2\x9d\x3f\x14\x2d\x2b\x0b\xbd\x2b\x2d\x26\x65\x3d\x5b\xaf\x9b\x07\xc5\xce\xe1\x0d\xfb\xef\xd1\x03\xdf\x86\x1d\xdd\x6e\xb4\x4a\x30\x7f\x78\x4c\xaf\xec\xd6\x3e\xd6\x34\xe2\xed\xaa\x6e\x4e\x06\x87\x30\xc2\x57\x02\x9a\xfb\x86\xbb\x49\x35\x05\xe5\x1b\xd1\x70\x2f\x83\x20\xba\x37\xb9\xa3\xaf\xd2\x5a\xb0\xa3\xa7\x3c\x38\x66\xf7\xd4\x00\xbd\x5b\x8d\x18\x0c\x48\x75\xca\x03\x7c\xc8\x26\x03\xc5\x29\xf5\xab\x7b\xb3\xa5\xc6\xa7\xa1\xd3\x01\x2a\xfb\x79\xeb\x7f\x6d\x0e\xf6\xa2\xc6\x98\x8e\xfe\xbc\xb0\xfa\x5b\x5d\x2a\xf8\x25\x76\x66\x78\x8d\xdc\xc1\xbc\xd8\x00\xf0\xb1\xbf\xe6\xe4\xa6\x2d\xb9\xfd\xfc\x47\x37\x64\x86\x01\x34\xc7\xf3\x7c\x6d\x43\xfd\x62\x87\xd4\xdf\xe1\x83\xa7\xa9\x3d\xf2\x36\x66\xc6\x47\x46\x91\xbb\x4d\xb4\xeb\x2e\x67\x26\x52\x55\xa6\x3a\x6f\xd0\xfc\x26\xf0\x73\x6f\x98\x3a\xa8\x99\xfd\x65\x28\xa1\x57\xb7\x1f\xd3\xb4\xbf\x6b\x6d\xb8\xa1\xb6\xaf\xfc\x91\x86\xe4\x4f\xd6\xbd\xcc\x9f\xbf\xcf\xe7\xfa\xdf\xf6\xb7\xee\xe5\x98\x4c\x7d\x3d\x2b\x6c\x2a\x1a\x6c\xd9\x9c\x8a\x97\x0e\x8d\x92\xb8\x7e\xc2\xe0\x78\x0a\x49\x77\xb4\x5b\xa0\x3d\x01\x82\x0e\x50\x40\x73\xbc\x90\x66\xc4\xec\x06\xcb\x84\x1f\x68\x72\x08\x09\x39\xd4\x2c\xf6\xe2\xba\x84\x49\xe8\x9b\x49\xe9\xfb\x72\x5e\x41\x40\xc6\xfa\xd4\x83\xd3\x04\x97\xd8\x03\x85\x8e\x23\xe8\x97\x05\xde\x78\xe8\x7e\x58\x97\xb5\x20\x65\x3c\x95\x85\x53\x48\xb8\x20\xdc\xa6\xb0\x93\x1e\x62\x05\x4c\x5a\x44\x0a\xc8\xfc\x0f\x1b\xce\xca\x21\xe7\x5f\xc2\xbb\xc7\x6d\x35\x7d\x28\xed\x61\xb6\x25\x40\x69\xf0\xd6\xb3\x9f\x67\xc6\x0b\xf8\x08\x79\xcc\x05\xdb\xe8\xd0\x5a\x73\x15\x9d\xdf\x55\x9e\xc3\x71\xb8\x6b\x08\xfb\xb7\x04\x88\xdd\xca\x42\xcd\xbc\x2d\xae\x06\x4f\x9d\x4f\x52\x80\xf0\xea\x77\x37\x78\xc3\x63\x2a\xba\x97\x52\x89\x2d\x7d\x9c\x2d\x77\xf5\x5d\xcc\x23\xf5\x69\x5f\x15\x59\x39\x81\xf5\xd9\x64\xd2\xfb\xcd\x28\xde\xc0\xc2\xd1\xb6\xda\x8e\xae\x3d\x4d\x8b\xa2\x30\x57\x33\xa8\x2f\x30\x4d\x6d\x2d\x23\xc2\x60\x4b\xcd\x48\x86\xef\x3f\xb6\x4a\x4b\x3b\xb9\x48\x15\xe2\xf1\xa7\xa0\x97\x87\x4e\xc9\xea\x06\xb6\xf0\x18\xea\x37\x0b\xb9\xd3\xe9\x0a\x9e\x08\xc7\xea\xbb\x2c\xb7\x1a\x07\x85\x68\x12\x9e\xd0\x7c\xcc\x2a\xca\xe5\x14\x94\x1a\xeb\x1f\x95\xef\xd4\xfc\x76\xe6\x0f\xc6\xb3\xaa\xc3\xab\x8c\x8f\x16\x08\x43\xfc\x48\x4b\xfa\xf0\x5c\x66\x45\x0f\xfc\xd9\x3b\xb9\x2e\xf6\x21\x9a\xc5\xdb\x1c\x22\x4f\x3b\x21\x67\x0b\xab\xad\xb8\x25\xa7\x51\xe4\x89\x06\x99\x96\xaa\x37\x25\x3b\xb4\x62\xdd\xdd\x31\x2b\xe2\x10\xd0\x33\x67\x93\x10\x04\x54\x8e\xe0\x79\x71\x94\x77\x43\x1e\x19\x70\x0d\x00\x3b\x82\x2f\x98\xf6\x7d\xc3\x55\xfe\x5a\xde\x31\x53\x92\x11\xa5\x1f\x9f\x6d\x2e\x5d\xae\x5b\xf7\xf0\x6b\x9b\x4b\xf6\x41\x82\xb1\xcb\x49\xfa\x92\x1a\x3b\x71\x2b\xf4\x42\x5d\x57\x95\xc1\x24\xd1\x16\xd9\x4c\x07\xbd\x43\xa7\x58\xc5\xc4\x91\x45\x6d\x8f\x89\xea\x75\x05\x3d\x97\x65\x15\x52\x4d\xf3\x34\x69\xce\x62\x81\x42\xed\xaf\x83\xfe\xd0\x69\x40\xbe\xfc\xc9\x2a\x6d\xa5\xfc\x3d\x9f\x76\xca\xe2\x21\xde\x07\xc7\x04\x0e\xeb\x75\x89\x22\xc0\x96\x39\xa1\x48\x87\x60\x1f\x1a\xd2\x18\x68\xd3\x4e\x4d\x55\xa0\xef\xea\x92\xae\xdb\x03\x05\x9d\x2c\x41\x1f\xd4\xcd\x89\x19\xef\xbc\x23\x43\x0e\xa2\x59\x5e\xac\x1b\xb9\xcf\x7c\x28\x4b\x53\xfe\x68\x4a\xc4\xf4\x14\x28\x09\x03\x18\x5f\x11\x42\x49\x0e\x9c\x2c\x4b\x30\xa3\x08\x04\x79\x45\xfa\xae\xf5\x4c\xfb\xc1\x60\xf5\x01\xe9\x97\x4d\xb4\x15\xc3\xc6\x76\x10\x49\xb5\x7e\x94\xa2\x6f\x71\x02\x28\x28\x58\xc2\x8b\x29\x74\x6d\xde\x3a\x57\x34\xd4\x0b\x26\x7e\xd2\x3c\x45\x3d\x3c\xe3\x2e\x19\xe0\x3d\xe8\x75\xcc\xa6\x83\x8f\x48\xa3\xba\xf6\x96\xa6\x6b\x25\x64\xd7\x3f\x04\x07\x9c\x2b\xeb\x23\xf4\xf8\xfe\x5e\x39\x6e\x3f\x06\xc1\xe9\x81\x75\xfb\xbb\xea\x42\xce\x41\xcf\x13\x85\x5e\x7d\x00\x77\x20\xba\xbb\x32\xf4\x1a\xdb\x46\x13\xdc\x36\xdc\xc9\xed\xe3\xb7\xcf\xb9\x28\xdd\x2d\x74\x18\xab\xcb\x4c\x3c\x57\xa0\x56\xd2\xe3\x18\x5e\xb0\x32\x03\xcb\xcc\x95\xad\x07\x96\x65\x1f\x15\xf2\xae\x2b\x79\xe5\x00\x65\xe5\x27\xab\x17\x16\x40\xeb\x11\xb4\xfc\x51\x60\x65\x9e\x6c\x15\xeb\xd5\x79\xb0\x24\xb5\x79\xa2\x3a\x54\xba\x5e\x29\xd6\x3a\xd5\xbd\x1d\xd6\xe5\xfd\xba\xa2\x80\x1f\x36\x0a\xd9\x43\xda\x2e\xce\x26\x8a\xfe\x29\x94\x3b\x30\xec\x1d\x21\x95\xc2\x69\x22\x6a\x45\xc4\xdb\xe7\x77\x3f\xda\xa3\x72\x2c\x7c\x13\xa6\x44\xfd\x2b\x2e\x63\x70\xef\xee\x2e\x87\x32\xfb\x88\x83\x8e\xb4\x79\x68\xa0\x05\x14\x9e\x92\xaa\xf8\x4d\x85\x43\x4e\x10\xf9\x5a\xed\x9e\xca\xe8\xca\x3a\x82\x06\xce\xcb\xc1\xa6\x34\x4e\x81\xa2\x40\x49\xe4\xf7\x21\x57\xa3\xfb\x9d\xd3\x2f\x34\xb8\x62\x60\x37\x1c\xe0\x66\xa5\xde\x98\xaf\x90\x21\x8f\xda\x62\x13\x7f\x6b\xf8\xdb\x3f\x7d\x48\x55\x1d\xe1\x2e\xcc\x64\xbe\xec\x7c\x93\xf3\x1b\x7f\xcc\x0f\xf7\x51\xe3\xfb\xe0\x0a\xc9\x05\xf3\x81\xc4\xf5\x07\x0b\x54\xfe\x1d\x0b\xff\x4c\xf9\xbe\xc6\x73\x2a\x2d\xae\xac\x1e\x0f\xf4\x29\x45\x20\x0b\x8b\x64\xe3\xcb\x0b\x53\xe3\x69\xf4\xbf\xd3\x33\x48\x98\x9a\x41\xdc\x95\xf8\xa9\x21\x21\x49\x48\x79\xdc\xe8\x46\x6d\x0a\x1f\x5f\x79\x7f\xda\xeb\x0d\x07\x83\xf4\x24\xc3\xd4\x4c\xc9\x97\xb6\xd7\x86\xce\xde\xff\xc1\x6a\x37\xdf\xf7\x3f\x57\x0e\xf6\xff\xe0\x8a\xfb\xe3\xf2\x07\xde\x06\x4f\x8c\x9b\x59\x6d\x00\x1d\x5a\x55\x55\xff\x0a\x47\xf9\xe9\xe2\xe9\xb0\x8f\xfc\x44\xb4\xeb\x6f\x4b\x27\x91\x76\xfc\xf0\x7c\x16\x58\xd8\xda\xe7\x8e\x4f\x75\x35\x39\xd8\x55\x48\xbd\x42\x1c\xbb\xcc\x85\x58\x11\x61\x5e\xe0\x2a\x5b\xc4\x34\x19\x57\x8c\x5c\x9f\x38\x3f\xe3\x4d\x08\xf2\x43\x3e\x47\xc0\x2f\x07\x8f\xaf\xe8\xfb\xac\x4d\xf7\xd9\xb7\xc2\xc9\x8c\xa1\x3e\x13\x08\xaa\xc5\x31\x27\xac\xe9\xcd\xa2\xb2\xac\x08\x84\x07\x09\x1c\xaa\x56\x6b\x8b\xef\x88\xb0\xd1\x80\x3b\x4d\x14\xa1\x4d\xd5\x78\x43\xe6\xc9\xa1\x0d\x97\xe2\xbb\x2d\x42\xba\x56\x65\x3d\xbb\xf1\x3a\x0b\xc1\x47\x33\x21\x26\xc3\xfe\x27\x24\xbb\xc9\x1c\xea\xb2\x14\x64\xcc\x72\xc6\x49\x10\x6c\x52\x5e\x05\x52\x57\x43\xe5\xf9\x42\xee\x37\x16\x54\x5a\x5a\x9b\xb5\xb2\x43\x6d\x9d\xcb\x2c\xf5\x4d\x57\x25\x5a\x04\x79\x80\x17\xcd\x51\x2e\xa8\x25\x61\xe3\xfe\x0e\x62\xac\x6d\x5f\xf9\x66\xfc\x96\x7b\x24\x26\xc4\xad\x04\xb2\xaf\x45\x57\x04\x5a\x9b\x19\x0b\x5f\x7a\xf3\xed\xad\xd3\x58\xcd\xc2\xe2\xa5\xed\xeb\x00\x4f\xff\x16\xe5\x93\x35\x7e\xea\x1c\xf7\x54\xf6\xee\x24\x74\x65\xdd\x7d\xd6\x75\xca\x16\xe7\x16\xe4\x8d\xd6\xbc\x10\x07\x29\x01\x37\xcd\x4a\x3f\x3b\x14\xd9\x89\x04\xf0\x38\x44\x17\xba\xe7\x43\xc8\xed\x3e\xff\x4b\xa7\x70\x60\x53\x50\xab\x73\x07\x1a\x8c\x6a\xbe\x3c\xbe\xc5\x87\x5c\xee\xbf\x72\x9f\x74\xd0\x21\x9d\xc1\x80\x64\x43\x5c\x90\x06\xe5\xa4\x99\xdb\x79\x2c\x76\x2e\xfb\x6d\xd5\xd6\x71\xf5\xaf\xed\x1d\xda\x74\xe1\x70\x5e\xe7\x24\x3c\xd1\x9f\x4a\x38\xf7\x37\x98\x26\x1d\x70\xba\xae\x4b\x8d\x2c\x5e\xc2\xe0\x3c\x8a\xb0\xa9\x71\x08\x95\x0b\x24\xc7\x35\x8b\xb8\x5c\x83\x66\xbf\xc1\x53\x3a\xa3\xe2\x8d\x7d\x4b\x3f\x93\xd6\xe9\x1b\x27\xa1\xd1\x3a\x43\x80\x1c\x84\x69\xfe\x59\x68\xc4\xb5\xb5\xd3\x98\xed\x6d\xd3\xaf\xa2\x12\x5e\xb6\x1b\x2e\x68\xa5\x34\x51\xb7\xb4\x4c\x37\xf1\x07\xbf\x4e\xcd\xc8\xd5\x1e\xd0\xe4\x2d\x97\x87\x25\xe2\x02\xbd\x36\x85\xb1\xb1\xd8\x09\x55\x80\xe7\xbf\x52\xfd\xea\x1e\xc7\x79\x33\x7f\x80\xd5\x61\xef\xfc\x15\xa2\xbc\x25\x62\x66\x92\x6f\xd7\x0d\x8d\x43\x3b\xa6\x9b\x17\xf5\x56\xb5\x44\x56\x6e\x0c\xf6\x2c\x1e\x1d\xcd\xd6\xcb\xf6\xda\xd1\x6e\x19\x87\x04\x4e\x97\x13\xad\x8c\xb2\xcc\xaa\xa4\x7f\xa2\xd1\x1b\x0c\x64\x16\xc3\x4e\x68\xc6\x4b\xc7\xea\xe2\xaf\xbf\xe2\xf8\xb5\xe7\xc5\x10\x95\xc3\x2d\x54\xbf\x51\xdc\xef\x31\x85\xbb\x5f\xe6\x7e\x8f\xce\x7d\x8c\xd2\x24\x14\x26\x28\x9f\x03\x92\xda\xc0\x0c\x07\xe9\xfa\xa6\x7b\x9f\x37\x52\x3b\x75\x9e\xfd\xfe\x43\xeb\x6f\x91\x1e\x7f\xae\xdc\xaf\x82\xff\x55\x7f\x75\x1f\xfa\x59\xfc\x8f\xf7\xad\x12\x34\x52\xe8\x5c\x8e\x71\xa0\xdd\x1a\xd1\xe7\x36\xa9\x59\x1a\x69\x6c\xd2\x92\xe8\x2e\x5b\xef\xdd\xa5\x58\x04\x60\x2d\x32\xfc\x85\x20\xc0\xb8\x4e\xf9\xc6\xbe\x75\xcb\xa8\x4d\x07\x3d\x5d\xfb\x7c\x2d\x67\x81\x5c\xff\x84\x24\x83\x97\x01\xcb\x90\xef\x82\x73\x89\xe9\xf6\xd4\xf3\xcc\x14\x28\x29\x92\x32\xab\x2a\x17\x4b\x15\xd7\x1a\xaf\xbc\x84\x0b\x30\x95\x39\x91\x2c\xc9\xac\xb6\x0f\xdc\x07\x12\x57\x97\xb0\x6a\x9e\x49\x2b\x89\x21\xd2\x7e\xe0\x6c\x80\xba\x9b\xac\xf3\x64\x46\x3e\xd8\x43\x34\x8d\x0f\x95\xd1\xf0\x82\xbc\x0d\xf4\x6e\xc1\x96\xfe\x5a\xc7\xf6\xa3\xf7\x5c\x5b\xde\x1a\x5b\xb2\x43\x96\xf8\xad\x59\xcb\x0f\x05\xd2\x7b\xcc\x51\x6c\x92\x49\x81\xbf\x6e\x23\x6d\xed\x93\x91\x56\x2f\x77\x1f\xbd\x53\x9a\x31\x82\x40\x73\x5f\x7e\xcf\x46\x12\xa4\xf0\x84\xfc\x77\xeb\xed\xf4\xd0\x1f\x4f\xa3\x8f\x20\x2f\x93\xd9\x95\x85\xe4\xa9\x4b\x9c\x3d\x21\xea\xc3\xac\x85\x76\xe4\x19\x3e\xa3\xaf\xee\x75\xa3\xb3\xb5\x20\xc3\xa3\x50\x52\x76\x2d\x25\x1d\xc4\xa4\xe8\xdb\x08\x02\xa0\x5e\xa2\xe2\xcd\xb2\xa3\x9d\x16\x0b\x96\xd5\xd4\x71\x38\x00\xe3\x37\xf3\xd3\x56\xf0\xa9\x33\x97\x65\x22\xb5\x0c\x15\x11\x34\xbd\xa2\x7f\xc9\x3c\xf4\x0a\x0f\x61\x29\x67\x0c\x5d\xb1\x87\x23\x56\x1b\xc2\x19\x7d\x3c\x23\xab\x0c\x6c\x6d\x08\x6b\x89\x74\x02\x16\xbb\xa4\x94\x0e\xa8\x5e\x56\xca\xce\x46\x09\xbd\x1b\x31\x03\x8c\xc5\x07\xb7\x92\xb3\x89\x26\x0f\x83\x20\x7a\xae\xc8\x94\x9e\x8f\xb5\xe7\xc5\xe6\xd5\x48\xe5\x33\x0d\x9f\x7f\x89\x9c\xbf\x80\xc6\x62\x35\x0e\x73\x31\xfc\xed\x52\xc9\x42\x15\x8d\x7e\x53\x21\x6f\x92\xd9\x5d\x35\x1c\x65\xb4\xed\xb8\xd5\x7e\xbe\x54\xf4\xb0\xf0\xfa\xb5\xa0\x84\x31\x38\x88\x93\x21\x44\xef\x62\x1f\x42\xea\xab\x58\x8c\x96\x71\x26\x54\xd5\x88\x12\x81\xac\xaf\x93\xbf\x16\xca\x38\x3c\x54\x4b\xbc\xa3\x56\xd3\x52\x10\x5e\xcf\x05\xe8\x70\x8d\x5d\xa0\xf1\x1a\x4f\x87\x35\x04\x82\x23\x61\x7c\x8d\x20\x83\xa3\x07\xcc\x75\x2a\x09\x9f\xda\x76\x6c\x35\x6d\xb6\x73\x9b\x52\x11\x98\x52\x90\x05\xb3\x0a\xce\xce\xf5\xe3\x13\xd9\xe4\x1c\x3d\xd7\x27\xbc\x08\x3c\xa7\xe9\x9b\xbd\xb3\xcb\xc9\x10\xb7\x8e\x1f\xfb\x8f\xad\xc1\xc5\x58\xff\xb9\xf2\x70\xa2\xfe\x71\xc4\xbd\xfd\x7b\x1e\x52\x43\xdf\xa3\xc4\x1b\x7a\xee\xc1\x8e\x87\xd1\x08\x6e\xf8\xcc\x3b\xcc\x47\x41\xe3\xee\x4e\x9e\xee\xe7\x13\x07\x10\x16\x90\x76\x85\x72\x35\x07\xd2\x17\xab\x62\x7c\xf0\x9b\x05\x99\x68\x7d\x66\x1d\x59\xa3\xe0\xae\x65\x59\xe1\x31\x74\xdd\x8f\xff\x5e\xe4\xb2\xcc\x45\x10\x56\xe0\xe4\x8c\xca\x01\x91\x69\xba\xce\x32\x2a\x63\xbf\xde\x98\x50\xfa\x81\x14\x68\xf0\x44\x8f\x31\xaa\x33\x9d\x4e\x5e\x09\xf0\x5a\x4c\xa3\xb2\x52\x5c\x29\x50\x87\x0d\xc0\xed\x7e\xea\xfb\x13\x89\xa1\xd4\x80\xe9\x6f\xe4\x83\xdd\x52\x5c\x19\xab\x5c\x1f\x31\x2d\xbe\x83\xa9\x9f\x2c\x0f\x06\x4a\x39\xd1\x07\xa9\xeb\xc7\xdb\x9d\x5c\x26\x2e\xa8\x61\x31\x88\xdc\x96\xd8\x70\x8f\xac\x83\x2d\x48\x13\x55\x12\xd6\x81\x08\x1d\x18\x9f\x8a\x50\xe2\xa7\x90\x22\xea\x64\x7d\x59\x5b\x32\x6a\x07\x46\xda\xf1\x7d\x51\xbf\xb1\xa2\x57\x56\xe6\xa1\x9d\x5e\xeb\x73\x64\x04\xd9\x13\xed\x6f\xf1\xe3\xe6\x14\x20\xb5\x72\x52\xe2\x4e\xb9\x37\x8a\xa2\x79\x58\x82\x6d\x6f\x40\xe8\xa8\x5d\x8d\xdb\x30\x19\xb8\xfd\x64\xfe\xf9\x12\xeb\xf6\x74\xd5\xe6\xd6\x17\xe3\xdd\x29\xb8\x63\xe6\x58\x1b\x0b\xa6\x5f\xb7\x02\x55\x9f\x9b\x10\x54\xd3\xeb\xec\x13\x0c\xc4\x7b\x6a\x5f\x85\xd9\xc9\x7a\x9d\x17\x97\x2b\x36\xf3\x2e\x9d\x9e\xe5\x93\x7b\x6e\x1e\x01\x09\xcd\x86\xc2\x08\xc5\xb6\xab\x25\x6a\x23\x15\x1b\x4e\x00\xe0\x1d\x42\x25\x54\xd4\x5d\x3c\x23\x3b\xcb\x47\xd1\x9b\xc5\x07\xc3\x05\xae\xa4\x2d\x70\xb9\x23\xf2\xb2\xcb\x9a\x0b\xa3\x39\x0a\x0f\x3d\x53\xe3\xdc\xe7\x74\xb5\xf3\xb1\x5c\x02\x3e\x1b\x24\x1a\x8e\x72\xdf\x71\x1b\xd6\xdf\x01\x34\xb1\x9e\xde\x43\x79\x42\x01\x72\x67\xbd\x07\xf4\x7e\xbb\x99\x39\x21\x8b\x0a\xfd\xe1\xa4\x03\xda\x69\xff\x63\xe8\xe1\x41\x9a\x95\x76\x2d\x91\x51\x9c\x68\x89\xcc\x0b\x23\x8b\xfe\x43\x4a\xba\xb6\x67\x73\x44\x9b\xb7\xc3\x08\xa3\x4e\x46\x48\x97\xae\x85\x19\x55\xdc\x2e\xfc\xa2\x06\x39\xba\xa6\x72\xa7\x6f\xda\x9c\x71\xb9\x54\x55\x8a\x72\xfe\x65\xc5\x33\x3a\x30\x77\x84\x1c\xe7\x3f\x03\xf6\x93\x12\xc0\x96\xbc\x77\xe7\x90\xa8\xb0\x4d\x0a\x13\xab\x0b\xc2\xd3\x52\xcc\xe9\x82\xd9\x62\x84\x6d\x5a\x72\xb8\x4d\x84\xc0\x49\x3b\x8c\x08\x05\x5b\x7f\x51\xf8\x06\xee\x53\xa7\x5d\x6b\x46\xda\xcb\x88\x70\xf3\x9d\x9b\xa3\x06\xd4\x30\x1e\x84\xec\x1a\x7d\xdf\xcd\xb8\xd4\x18\x6f\x37\xab\x00\x5c\x47\xce\xae\xf2\x18\x91\xc8\x3c\x3c\x1f\x3f\x28\xf9\x55\x1f\xe4\x97\x28\xcd\x04\x37\x62\xe8\xdd\x14\xfe\xd0\x4d\x9e\x1a\xb2\xf3\xe2\xf7\x9e\xbd\x1a\xe1\x4d\x61\x31\x75\x74\x8c\x8c\x4a\xa2\x2c\xdb\xaf\xc4\x61\xa3\x6f\xc6\xdc\x11\x99\x1c\xba\xec\x38\xf5\xb0\x71\xc2\x4f\x96\xad\xad\x9f\x00\x31\x8f\xf3\x5a\x0e\xf9\xf9\xce\x12\x00\x5a\x19\x04\x41\x41\x54\xd6\x69\x8e\x77\xbb\x35\x9b\xa4\x4c\x82\xfe\xe0\xc9\x56\x31\xff\xc9\xfa\x52\xcb\xf2\x77\x7e\x10\x94\x25\xf0\x7f\xf3\xd1\x08\x75\x25\x27\x41\xd4\x04\x37\xf7\xb9\x05\xa1\x0c\xe3\xfa\x63\xcb\xab\xac\xcb\x3e\x3b\xc1\xb7\x10\xa4\xd0\xb1\x09\x1b\x83\xa7\xbe\xfa\x16\x01\xac\xd2\xa4\xe2\x3d\x2f\xae\x0d\x15\xfa\x21\xf0\x7b\xc6\x39\x4c\xdd\x26\xbc\x2d\x0b\xa8\x2c\xe5\x35\x00\x1f\x70\x42\x96\x09\x66\x73\xc3\xa4\xff\xc6\x84\x02\x48\x8a\x40\xae\xaa\x24\x0d\xde\x57\xe8\xad\x72\x8d\xe6\xb3\x44\x28\x90\xab\x52\x6e\x39\xc7\xe5\xfa\xfb\x97\x87\xc1\x81\x18\xe4\xd6\x88\xb8\x5b\xb8\x26\x2c\x5e\x13\x59\x54\xe7\x59\xae\xc9\x7d\x1a\xc9\xda\x23\xca\x53\x13\xad\x91\xcb\x15\x93\xd5\x11\x87\x27\x2c\x79\x62\x6b\x55\x7d\x11\x59\xce\x71\xf9\x72\x0f\x4b\x10\xe7\x5b\xab\x4d\x3e\x9f\xf3\x55\x07\xbe\xdd\xfd\x24\x34\x66\xe0\xf9\x32\x4e\x8e\x02\x0e\xcf\xf3\xa1\x4f\x0f\x98\x51\x04\x01\x96\xa4\xe5\xb8\x21\x05\x04\xff\x71\x1a\xf8\xf2\x98\x34\xd1\x9c\x1a\x0f\x41\x51\xe3\x3a\x47\x8f\x21\x91\x9f\x1f\x16\x8a\xe7\x0d\x58\x7b\xc8\xc5\x22\x7d\x65\x1a\xc9\xb3\x82\x7f\xa0\x2a\x01\xd2\x52\x01\xca\x54\x4e\x30\x5a\xfa\xb4\x13\x07\x6b\x05\x96\xcc\x44\x4d\x90\x8e\x76\x3a\xcd\xc0\xb8\x70\xbe\x84\x99\x58\xb9\x47\xd5\x54\x37\xcb\x2f\x2a\x34\xf9\x1d\x9b\x85\xa7\xb8\x6b\x79\xeb\x9a\xbc\x66\x35\xfd\x0a\xc6\x75\x11\x23\x03\x2e\xed\x5a\xe5\xe4\x5a\x5c\x01\x8b\x64\x64\x12\xa4\xb4\x35\x6f\xf5\x1a\xfd\xea\x7b\xcb\x2b\x84\xb1\xad\xf6\xa7\xff\x5a\xe2\x7e\x9b\x59\x4f\x56\xb3\xb9\xec\x1d\x4f\xa0\xf9\x8a\xea\x82\x56\x68\xd6\x99\xcf\x81\xaf\x31\xc9\xbc\x37\x73\x9b\xd5\x1e\xfa\xcc\x18\x66\xb8\x23\x58\x3c\x01\x62\x7d\xbc\xd7\x7a\x5b\x89\x52\x80\x31\xf8\x59\x84\x06\xdd\xdd\x19\x46\xb5\xa3\xd0\xb0\xfb\x63\x9c\xc5\x3c\x8d\x4b\x37\xb5\x59\x39\x08\xcd\xcb\x8f\x6d\xba\x0d\x13\xc1\x3e\x7a\x6c\x74\xf5\xd9\xfd\x78\x59\x3b\x98\xcd\xab\xf8\xfc\x6a\x59\x2c\xbb\x83\xdb\x1e\xe7\x86\xc2\x6f\x1a\x6a\x73\xac\x60\x30\x62\xaa\xcb\x39\xf5\x64\x8b\x2d\x32\x04\xfd\x38\xd9\x8b\x0d\xcd\x34\xe5\x32\x70\xf7\x10\x28\x6c\x16\x20\x00\xc3\x0d\x1f\xbc\x53\xd0\x23\x06\xb7\xd0\x08\x08\xab\xca\xc5\x0b\x3a\x98\xd9\xf2\x74\x42\x47\x4b\x55\x09\xea\x07\x16\x3c\x9e\x3a\x51\xdb\x72\xf1\x07\xe8\xa5\xaf\xba\xc1\xd1\xa4\xbb\x74\x0b\xe1\x46\x11\x91\xe6\x25\x3f\x39\x2f\xef\xf2\x8c\x01\xcb\x39\x1c\x5e\x2f\xbe\xac\xfb\xf2\x02\x0b\x99\xd5\x62\xf0\xa7\x74\x44\x5f\x17\x9d\x4f\xea\xc2\x4b\x1f\x1f\x9b\x38\x5a\x53\xf8\x29\x8c\x81\x0b\xad\x57\xe0\xee\x4b\x39\xa7\x90\x49\x4b\x44\xe8\xba\xbe\x9a\x1c\x44\x92\x72\x0b\xcc\x0b\x66\xfa\xb4\x49\x74\x6f\xe9\x88\x15\x73\x6f\x02\xc9\xd6\xe4\x18\x9d\x9c\x86\x4e\xa5\x1e\x7d\xb5\x70\x37\x77\xf2\x01\x4d\x45\xa4\x54\x81\xbd\x27\x92\xe0\x9c\x67\x75\x81\x2d\xc7\x54\x4f\x94\x9b\x49\xc4\x38\xa2\x5d\x39\xc9\x6f\x7c\xf9\xae\xb8\x92\xea\x78\x59\x75\x69\x8b\x5e\x7f\x65\x0c\x23\x43\x1c\x6f\xad\x96\xda\xb7\x7f\x38\x63\x8e\xe7\xcf\x05\x99\xa9\xf8\xff\x8b\x14\xcf\xfa\x94\x1e\x7a\x81\xb0\xd1\xdd\x23\x84\xd7\x22\x08\x1f\x3f\xe0\x6d\x5f\x80\x64\x00\xe5\x35\xbb\x65\x89\xe1\x43\x0d\xea\x83\x3c\xa0\x11\xa9\x7b\x2b\x12\xd5\xaf\xb5\xf5\x1c\x9a\x2d\x73\xd3\xfa\xc7\xaa\x8b\x07\xd5\x84\xb3\xc4\xdd\x9a\x8c\x55\x35\x94\x98\xc1\xab\x85\x2e\x0d\x5f\x75\x5d\xd1\x65\x59\x55\x95\x9b\x68\xea\xf3\xd3\x4c\x55\x48\x70\xa0\x85\xb7\x00\x4c\x64\x96\x40\xc5\x40\x27\x68\x64\xc1\x72\x11\x0d\x49\x19\xfe\xaf\xfb\x79\xac\x4e\x4a\x04\xf0\xc4\xd4\xad\xdc\x96\x94\xe8\x99\xd9\x39\x69\xa1\xd1\x17\x0f\xc2\xb5\x37\x2b\x5e\xeb\x59\x0f\x49\xf5\x80\x39\x04\x05\xa8\x79\x00\xe4\x59\xb2\xb5\x98\xa0\xfb\xbd\x76\x8f\x42\x0f\xab\x3f\x8c\x9b\x50\x09\xc2\xce\xf4\x83\x71\x66\x57\x4a\x1e\xe1\x66\x3c\x14\xb9\xcb\x77\xa7\xa4\x19\x32\x54\x27\x1b\xbc\x36\x0f\x76\x4d\xd2\x0e\xc4\xd7\xbe\x3a\xfd\x2c\x79\x90\xc3\xa5\xf7\x0f\x34\xb7\x8c\xa7\xf7\x4c\xff\x07\x1f\xdb\x4e\x2e\x14\xe6\xb4\x74\xb4\xac\xe9\x77\xac\xf3\x49\xae\xb8\xab\xda\x8a\x32\x26\xee\x2a\xde\xfb\x5c\x08\xbb\xac\xf4\xbf\x3e\x7f\xb5\xf8\x22\xe4\x32\xad\x72\xed\x41\x25\xdf\xe8\x05\x01\xed\x04\x8f\x7f\xf4\x04\x62\x28\x6e\xab\x38\x54\xf2\xf9\x73\x8f\x9b\x70\x47\x45\x8b\x57\x6a\xec\x1e\x5e\xf0\x60\x62\x47\x36\x4b\xae\x59\xf8\x7b\x70\x11\xf4\xc9\xdf\xb4\x2b\xec\x0d\xf1\x6f\xd3\x83\xf5\x41\x31\x79\xc6\x39\x45\x43\x0a\x17\x8a\xb6\x9d\x20\xe2\x2a\xbb\x15\x02\xd0\xc7\x44\xc6\x6d\x6d\x6c\xc1\xa7\x9a\xe1\x53\xec\x43\xaa\x56\x6e\x58\xbc\xc6\x65\x9d\x63\x6e\xb3\x98\x25\xab\x8f\x27\xc9\x0a\xde\xc6\x80\x0e\x81\xe0\x51\xdb\x5d\x36\x0a\x65\x79\x53\xe5\xb5\xaa\x5a\x81\x97\x62\x56\x80\x63\x15\x62\x0b\x99\xd9\xb6\x99\x20\xb3\x1c\xd8\xc4\x45\xd4\x1c\x76\x8d\x76\x15\xfd\x60\x93\xca\x5e\x47\xc8\xb0\x30\x39\x08\xa7\x74\x2c\xe8\xde\x7f\xb2\xf7\x94\xe3\x83\x23\xee\xb0\xac\x33\x28\xa6\x3f\x3a\xd0\xfb\x5e\xc6\x8d\xdb\xd2\xa9\x87\xbf\xa5\x61\x7e\x39\x91\x1e\x7b\x82\x56\x5d\x6a\xa3\x5d\x48\x50\xcd\xe2\xac\xb3\xb8\xa4\x25\xeb\x24\x4c\x8b\xd7\x01\x3d\x26\x56\xa4\x91\xd5\xd5\x13\x6c\x69\x64\x91\x28\x37\x8d\x1c\xac\x9e\xa2\xd2\xb9\xad\x07\xcb\x1b\x2c\x8b\xef\x6d\xae\xcb\x1b\x19\xba\x28\xe6\x3c\x70\x56\x09\x11\xb6\xb4\x49\x4f\x0c\x5f\x97\x84\x6b\x66\x02\xb0\x26\xaf\x8e\xaa\xaa\x05\xeb\x4c\x8a\x47\x8d\xbf\x2c\x57\xb6\x99\x05\x53\x7c\x1c\xde\xe3\xef\x87\x88\x38\x44\x7d\x2a\x13\x5d\xb3\xa9\x17\xf1\x04\x7f\xf5\x48\x44\x35\xac\x07\xba\x06\xa2\xfc\x89\x9c\x56\xfd\x34\x3d\x5c\x47\xa3\x31\x90\x17\xd8\xc2\x4b\x1e\x79\x16\x79\xa8\x85\xc7\xe7\x59\xa8\x25\x2b\x67\x47\xf7\x09\x0e\xf8\x52\xdd\x19\x3f\xb9\xe2\xee\x51\x42\x48\xd3\xe8\x58\x48\x17\x0c\x52\xb1\x82\xfe\xb1\x0d\x86\xfb\x4f\x66\x6c\x66\xe1\x1f\x98\x71\x58\x3c\xcc\xfb\x56\x65\xd6\x10\x84\x37\x1c\xba\xd9\x0d\x19\xd6\x19\xeb\xde\xbd\x5a\x67\x02\x3c\xdf\x67\x97\xb2\xad\xbd\x47\xcf\x12\x01\x1c\xae\x8f\xd9\x11\xf1\xbb\xc4\x6a\xa3\x4c\x67\x3c\x6e\x68\x33\x19\x0f\xa2\xfc\x38\xbc\xbc\x37\xf2\x1a\x0c\xc0\x68\xe3\x1d\x09\x7e\x42\xc0\x66\xa8\x7f\x9c\xc9\x99\x12\x14\x86\x11\xc4\x36\x20\x02\xcb\xf3\x18\x33\x10\xd4\x65\x15\x98\x26\xc5\xad\x69\x11\xb9\xf4\xa3\xfd\xb0\x25\xb1\xf7\x18\xaf\x21\xdd\x7f\x99\x42\xf1\xd8\xf6\x32\xd3\x21\x21\xcc\x72\x5a\x60\x44\xb5\xc4\x7c\xf5\xc3\x79\xb6\x3c\x69\x50\x2e\x57\x2e\xa9\xb6\xb0\xb9\xc3\xb2\x6b\x0a\x06\x1c\x9b\xea\xa7\xdc\xb9\xa1\x05\x63\xfe\x32\xe0\x13\x60\x73\x33\xfb\xe1\x71\x43\xa8\xea\xd7\x20\xbb\x0c\x6b\xa7\xdf\x8e\xd6\xe1\x38\x6f\xba\xce\x45\x07\xe9\xdc\x30\xc7\xad\xec\xb9\x5e\x0b\x8c\x12\x4c\x85\x27\x44\xfb\x15\xc5\xee\x89\xa5\xcc\x21\x96\x7f\xca\x80\x92\xda\xc8\xe6\x58\x2f\xab\x33\x46\x0f\x38\xc1\x50\xb5\x2f\xc6\xcf\x76\x4e\x00\x66\x4c\xfa\x20\x24\x80\xa8\xb6\x36\xcd\x75\x70\x4a\xd0\xeb\xb9\x97\x9a\x7c\x75\xfa\x85\xa9\x7a\xea\x32\x27\xba\x87\x41\xbb\x01\x48\x4b\x06\x72\xa0\xc6\x6e\xf6\x42\xbe\x57\x08\x3e\x99\x4c\x27\x49\xc7\x8c\x64\xd7\x81\xa9\xf0\x06\x76\x9a\x51\x8b\xfa\x7b\x91\xde\xb7\x0f\x09\x6e\x85\x7b\xa9\x3b\xbf\x37\xce\x39\xd7\xd9\x5b\x7d\x2d\x86\x0b\xa7\xbe\xa8\x40\xa6\x48\x27\x8f\xec\xb6\x0a\x9c\x30\xe1\x5b\xa3\x5a\x0e\x1a\x88\x53\x73\x99\x1e\x1d\x23\xa1\x96\x77\x6d\x95\xdb\xf4\xbe\x3a\x55\xe3\xe7\xa0\xb8\xfe\x74\xd5\xc8\x98\x86\x9a\x64\x5a\xe7\x3a\x7e\x59\xe6\xfc\xd9\x29\x89\xd5\xfb\xa3\x12\x3d\xf6\xb6\xc0\xd9\x64\x7a\x5f\x35\x7a\x70\x15\x90\x85\x8b\x59\x5c\x3d\x7a\xd2\xa9\xc2\xef\x4d\xd3\x59\xdd\xd6\x82\x4b\x19\xee\x7e\x53\x32\xfc\x8d\x10\xc8\x5a\xac\x83\xf4\xc2\x4b\xb0\xf9\x34\x86\xb6\xe3\x2b\x6b\xee\x28\x82\xaf\x1e\xde\x64\xb1\xa5\x43\xfc\xb4\x7b\x2e\x63\x81\x82\xd9\xf8\x0d\x26\x56\x48\x16\xd6\xdb\x9c\x83\xbd\xb0\x63\x86\xdd\x83\x74\xcd\x4d\x7d\x5a\x6b\xe5\x79\x1a\xad\xfa\xd8\x03\x46\x19\xda\x8a\xb9\xf4\x5b\xe9\x17\x25\xc1\x69\x5b\xcb\x2e\xab\xeb\x0d\xdb\x63\xd5\x56\xde\x3e\x99\x34\xd3\x86\xaf\x3b\x48\xd4\xe9\x43\x52\x03\xeb\x6b\xb7\x27\x01\xa6\x1d\x8b\xe5\xce\x62\x69\x50\x9b\x3a\x35\x4c\x44\x94\xcd\x6c\xba\x9a\x2c\x5b\xd5\x24\x9a\x46\x24\xea\x7a\x68\x10\x8f\x5f\x05\x43\x11\x73\x59\xa7\x23\xe3\xd6\x60\x12\xcb\xd5\xee\x8f\xe0\x1a\xa9\xe6\xec\x5c\xf6\x81\x28\x63\x9e\x89\xf3\xa6\xdf\xf3\xf3\x4f\x3b\x57\xa8\xf6\x22\x06\xcc\xc6\xca\xdf\xa7\x89\x5b\x4b\xc1\x3c\xa7\x08\xd3\x4c\xd7\xd2\x91\x57\x1b\x7e\x67\x59\x10\xf9\xeb\xfa\xa3\x10\x00\xfa\x28\x62\x42\x7c\xe5\xf8\x01\x05\xf6\x9b\x88\x54\xba\x79\x91\xa6\xa5\x48\x99\xe9\x33\x31\x86\xef\x8f\x1c\xb7\x17\xcf\x9f\x6d\xfd\xf7\x1f\x77\xff\x8f\xbf\x6a\x8e\xd8\xaa\x0c\x7d\x3c\x8a\x59\x82\x7b\xce\x18\x95\x2c\x0d\x84\x3c\x65\x02\x61\xa1\x77\x87\xb7\x17\xe1\x8e\xa1\xec\x44\xa4\xce\x9e\xbc\xee\x37\x06\x05\x40\x1b\xf9\xc9\x22\xab\xdd\x3e\xe3\xf6\xe2\x3c\xd4\x87\x42\x20\xdb\x40\xa6\xbe\xf0\x91\x09\xca\x88\x94\xe3\x1b\x79\x67\x27\xe6\x29\x80\x72\xfd\xbd\x97\x45\xa5\x4d\x13\x62\x99\x05\x41\x9c\x2e\x4e\x6c\xf7\xef\x62\x09\xaa\xec\x89\x2a\xe1\xbf\xe5\x44\xe8\xd8\x5f\x5d\xea\x50\x6d\x31\xb1\xb4\x25\x45\x82\xc8\x82\x4e\x81\x1d\x15\x90\x3c\x28\x53\x63\x91\x15\x3c\x95\x2c\xdf\xb1\xac\x97\xdf\xec\x2a\xa4\x59\xdf\xdd\x4c\x53\x79\xc3\x19\x2f\x1f\x0e\x73\x63\xf2\x3a\x47\xe0\x08\x5d\xfb\x85\xa2\x6b\x29\x92\x8c\xef\x34\xaa\x3a\xa1\x4e\x87\x01\x67\x3d\x5a\x5c\x3e\x48\xcb\x8e\xd5\x72\xca\xcd\xcf\xde\x05\xf7\xd5\x1f\xdb\x44\xc5\x2b\x92\xa4\xdb\x54\xf0\x28\x74\x5f\x39\xef\xc9\x0b\x97\xec\x7d\xea\xe8\x47\xc8\x89\xcb\xeb\xe0\xe0\x66\x6a\x34\x15\x09\x32\x28\x18\xc9\x16\xd8\x1e\x28\xb2\x20\x7f\xf4\xe2\x2e\x2f\xaa\xf6\x5c\x9e\x45\x31\x6c\x97\x19\xf3\x84\x55\x6d\x9f\x15\xe1\x5b\xd3\xdd\xa2\xae\x8e\x2d\x39\x66\x88\xd7\x6f\x42\x83\x28\xba\xd3\x4d\x54\x13\x83\x60\xb7\x02\xb3\x2b\x8d\xf3\x40\x42\x5d\x18\x9d\x44\x73\xaa\x12\x7c\xa1\x13\x16\xf8\x2e\x7a\x7c\x1f\xab\xc1\xd9\x55\x75\xd5\x53\x82\xaf\x2b\x45\x41\xe8\x1c\x36\xd5\xa1\x3d\xe0\x85\x1f\x19\xcf\xae\xa6\xba\x58\xa6\x73\x99\x7d\x82\xf1\x0f\x47\x6c\x5b\xaf\x24\xaa\xa8\x75\xd6\x51\x05\xd4\x93\x9b\x70\x6f\xb9\xe2\xb9\x1e\x19\x47\xc9\x37\xf3\x96\x15\x4d\x0e\x9f\x51\x07\x0a\x73\x7f\x35\x75\x7b\x6d\x3a\x55\x96\x4e\xf9\x81\xf4\xb3\x89\x26\xe2\xae\x45\x72\x10\xbd\x9a\x28\xdb\xa7\x84\x4c\x8d\x2d\xad\xc4\x1b\x67\x4c\x5e\x01\x5e\x42\xbe\xf9\x96\x3f\xef\xad\x8e\x8b\xc5\x06\xa0\x4e\x18\xd2\x95\x14\xef\x5e\xdc\x07\x5d\x51\xa5\xf4\x7c\x35\x7d\x9a\x68\x76\x30\xa2\x21\x9c\x09\x40\x5a\x61\x1e\x14\xe4\xb9\xac\x26\xcd\x70\xa9\x56\x44\x70\x51\x88\x6e\x37\x2c\x74\xf7\x23\xa0\x4b\x5a\xb6\xe6\xf7\xb0\x00\xb9\x4e\xc2\xe4\xcd\x8d\x17\xc6\xa7\x37\xe8\x95\x96\xcf\x9d\x23\xd5\xb4\x60\x2c\xc5\x4d\xa6\x99\x8a\x06\xfa\xf2\xe8\xb7\xca\xb1\x0e\x3b\x72\x76\xe2\x2d\xa4\xb6\x12\x87\x31\xa0\xe8\xe9\x92\x08\x21\xbd\x27\x2e\xbc\x46\x48\x24\x74\x4b\x82\x19\xde\xcd\xca\x25\x80\xbb\xf4\x8c\x79\xb0\x5c\xac\x70\x4d\xc2\xa3\xb5\x93\xab\x46\x16\xbf\x13\xbd\x66\xac\x9e\x45\xcb\xbd\x04\x96\x90\xf1\x53\x0d\xa5\xaa\x22\x66\xf1\xa7\xfe\x16\xf4\x96\xcb\x5a\x1b\x72\xde\x1a\x8b\x03\xe0\xba\x28\xfb\xf2\xfd\x11\x06\xf6\x9d\x9c\xfb\x0e\xe8\x3b\xc4\x9b\x6e\x2d\x6b\x28\x39\x30\xf8\xe7\xc6\x6c\xc8\x2a\x57\x56\x42\xfe\x04\x53\x3e\xf7\x10\x52\xbd\xed\x88\xcc\xb7\x87\x14\xf5\x37\xd2\x99\x17\x5c\x0d\x14\xcc\x91\x0c\x53\xd3\x4a\xf9\xae\x4c\x43\x41\xbc\xf1\x07\x37\x5b\xcb\xe5\x4f\x36\xf0\x1c\x87\xbf\xaf\xf7\xfd\xaf\xf7\x89\x2a\x5d\x60\xf9\x80\xde\x8a\xd9\x5d\x79\x1a\x52\x03\x18\xc5\x7d\xa5\xf0\x15\x1d\xd6\x66\x58\x51\x41\x4a\xe8\xa2\x13\x39\x0f\x65\xf5\x8c\x0f\xe5\xa8\x7b\xde\xb6\xdd\xe6\x9f\x4c\x58\x68\xc1\x83\xbc\x78\x81\xd8\x84\x5c\x64\xba\x7d\xf5\x4a\xbf\x98\xe9\x1a\x61\x61\x4e\xa9\x33\x42\xb4\x9b\xc8\x29\x92\x22\xa8\x87\x20\x1a\x43\x87\x6e\xa7\x22\xce\xca\xda\x57\x22\x81\x5d\x3b\xbe\x61\x5b\xa1\x7b\xee\xb1\xd3\xc1\x4f\x52\x24\x94\xc9\xe6\x45\xea\x31\xd9\x7e\x58\x76\x02\x1f\xd9\xcb\x1a\xd3\xb3\xa5\xc3\x2a\x2d\x9e\x9d\x95\xaa\x77\x2d\x64\x34\x77\xcb\xda\x0e\xde\xb6\x47\x91\x1e\xde\x65\x63\xda\x6b\x6a\x1a\xdf\x86\x79\x7c\xf6\x23\x32\xa2\x49\x33\x66\xeb\x8f\x89\x7e\x88\xf0\xce\xcf\x29\x11\x0f\x3d\x64\xd7\xb2\xaa\x8e\xfa\xab\x3c\xc8\x0a\x33\xe7\xe6\x47\x8e\x7f\xdb\xf7\x67\x07\x35\x18\xfc\x44\x13\x82\x0f\xf3\x77\xa8\x1a\x1f\xc3\x96\xfc\x22\x2a\x4f\x0f\xa3\xe2\x70\x5a\x94\x41\x5e\x99\x68\xc0\x44\xd5\xa8\x2e\x0d\x9a\x82\x49\x32\x73\xc6\x93\xfb\x45\x2b\xc0\x0d\xf9\x6e\x6b\x3d\xc8\x51\xd2\xdc\xfc\xc2\x4d\xf6\xbb\xc1\xca\x97\x3d\x16\xed\xcf\x45\xb4\x70\x4e\x99\xe6\x52\xcb\x28\xd4\x6d\x96\xa3\x7f\x1c\xb5\x1c\xa4\x95\x46\xbc\xe3\x77\xb7\xd9\xf1\x89\x2d\x34\x89\xbd\x50\x1a\xfc\xf2\x4e\xbb\xc6\x0e\xdb\x5b\x07\xf8\x61\xe4\x5c\x7b\xe2\x2a\xd9\x1a\xff\x63\xb4\xda\x1f\x59\x3c\x12\x39\x8c\x1e\xda\x85\x91\x05\xb5\xcf\x9a\x74\x52\x25\x31\xd6\x18\x6e\xb5\xd1\x84\xe7\x20\x93\xce\x2a\x6d\x98\x49\x53\x7e\x6e\xf1\x6a\x82\xfa\xf5\xa4\x81\x46\x9e\x7e\x1e\x3b\x09\xac\xcb\x9a\xa9\x39\xdf\xd1\x2f\xbc\x4a\xb9\x8c\x49\x16\x03\x00\x0f\xa9\xf7\xe9\xa5\x2f\x3c\x1a\xb4\xee\x84\xb6\x9e\xe9\xb8\x0b\xff\xed\x62\x1a\x04\x12\x7d\x55\xa4\x4e\xab\x75\xaa\xbd\x40\xfc\x73\x0e\x58\xac\xf5\x54\xe6\xe1\x5f\x1a\xc8\xdd\xe4\x8e\x10\x27\x5a\xd5\xd8\x7c\x6f\x51\x42\x3e\xcd\xc3\x5c\x07\x2c\xc4\xb9\xa9\xac\x75\xf5\x49\x7f\x52\xa5\x22\x6b\xa6\xab\xfb\x53\x7f\x05\x8d\x3c\x13\x62\x2c\x33\xc8\xe3\xaa\x71\xd1\xcc\xf4\xaf\xdc\x22\x31\x50\xa3\xe5\x12\x9e\xe4\x2e\x98\x79\x9a\x38\x9c\xb4\x6c\x22\xe6\x6f\x1d\x35\xd1\xe7\xd6\xad\x27\x27\x9d\x98\x27\x89\x1a\x15\xe4\xfc\x03\xfa\xab\x1a\x27\x1a\x8a\x3f\x59\x91\x5f\x82\x00\x47\xc8\x64\xd7\xdd\xeb\x7b\xd6\x7b\x77\xd5\xea\x14\x11\xb9\x5a\xad\x6c\x71\x44\x1c\x91\x9e\x35\x71\x3f\x5c\x73\xbd\xec\xba\xa7\xcc\x75\x6b\x7c\xf6\x59\x50\x8f\x78\x5e\x70\xdf\x68\xb7\x58\xa3\xc2\x23\xc7\x4c\x69\xfd\xbe\x49\x8e\xa4\xf5\x37\xa5\x84\x59\xe9\x8a\x63\xe6\x2a\x99\xe2\x26\xa1\x77\x21\x31\x55\x5f\x52\x6c\x05\xd1\x7d\x1e\x4a\x33\x34\xdb\x20\x86\xb8\x37\x88\x98\x17\x7f\xa4\xe6\x28\x9f\x3f\xd9\x15\x06\xf3\x7f\x2e\x44\x40\x3d\x79\xfc\x6d\x28\xfa\x6c\x40\xf2\x5d\x8e\x62\xe2\xf0\xe0\xd3\x76\xaa\xca\x36\x24\x04\x8a\xd0\x31\x4c\x31\xcb\xfd\xc6\x71\xd2\x19\x29\x2d\x6a\x4c\xd2\x11\x01\x12\xdb\x85\x28\x44\xda\xa0\x3d\x4a\x9e\x93\xb2\x8e\x33\x37\xb2\xd2\x56\x75\xdb\x32\x32\xeb\xd9\x27\x4c\x8d\x52\x35\xe5\x84\x2e\xe5\x80\x3e\xf0\xac\x5a\x3c\xc9\x87\x51\xd8\x57\x01\x39\x81\x10\x13\x87\x67\xb3\x19\x7f\x8f\xa2\xb1\xb8\xd1\xdc\x65\x47\x94\x20\x8c\x4a\xbd\x49\x10\xd4\x4e\x88\xf8\xa8\x77\x39\x7f\x57\x6a\x02\xff\x00\xb0\x00\xca\x11\x70\xb2\xb4\x4e\x85\xf2\x82\xc9\x95\x5f\x92\xfb\x53\x6b\x24\xc9\xfb\x95\xb5\xa4\xdf\x54\xb9\x64\xe3\xe6\x72\xf1\x36\x4c\x89\x2b\xab\x27\x22\x56\xf5\x7a\x5e\xa9\x6d\xb7\xd0\x5c\x99\x5a\xbc\x14\xf8\xb4\x98\x5d\x0f\x91\x06\xbd\xa2\xb2\xab\x5c\x9e\x27\x31\xa1\x71\x32\x7d\x87\xd2\xe2\x56\xe5\x16\x32\x0d\xe0\x18\xe4\xd4\xa2\xfe\x3b\x04\xbc\x43\xea\x31\x6e\x49\x1d\x74\xba\x8b\xaf\x42\xcd\xf3\x55\xde\x18\xee\xfe\x31\xcd\xfc\x6d\x22\x5b\xb9\xe1\x68\xc7\xbf\x4f\x3b\xe2\xa0\xf4\xe2\x04\x17\xa5\x12\xff\x5c\x4a\x84\x74\x37\xc1\x46\x64\xd4\x55\xa6\xe3\x17\xdc\x60\xce\x4d\xe3\xa3\x15\x1d\x74\xb2\xc6\x5a\xd9\x48\x05\xbf\x57\x5e\x55\x58\xa8\xe3\x03\x48\xc6\x3d\xc9\x2f\x74\x90\x48\x23\xc3\xce\x25\xe2\x08\xa0\x09\xf4\x4e\x76\xec\x94\x5c\x4b\xae\x26\x7d\x2f\xb6\x7c\x2c\xf7\xf2\xc7\xed\xd1\xc9\x25\x20\x2a\xf2\x38\x0c\x49\x9a\x85\x03\xe4\x58\xa7\xad\x0e\xf0\x98\x8f\x42\xaa\xa4\xfd\xb0\x59\x0a\x50\xda\xfa\x55\x62\x31\xbc\x52\x22\xf7\x72\xd2\x6f\x32\x21\xbe\xcd\xa4\x52\x6c\x12\xbd\x00\xdd\xd6\xf8\xf2\x03\x24\x9b\x8e\x21\x08\xa1\x73\x81\xa4\x83\x43\x14\x2b\x2d\x14\xa9\xc8\x33\x51\x5d\x4b\xb0\x5c\x83\x42\xba\x7d\x66\x0f\xfd\x82\xd1\x92\x68\xce\x6d\xf5\x19\x69\x3e\x89\x06\x9f\xba\xe4\x42\xa1\xcb\x8c\x9a\x94\x10\x9a\xe8\xd5\x29\x82\xfa\x99\xcf\xad\xc2\x3b\xc1\x77\xa8\x1d\x31\xa9\xcd\xce\xb8\x10\xf2\x9b\xdd\x88\x25\x99\x44\xe1\x1c\xd5\x1c\x6e\x91\x0f\xa0\x40\x09\x44\x1d\x7a\xd1\x6e\xa6\x2d\xf3\xb7\x2f\x51\xf6\xe0\xbb\x21\x95\xdc\xef\x74\xe4\x58\xf4\xd9\x27\x70\x9d\x81\x3b\x7e\x15\x4b\x6e\xd5\x95\x73\xd3\x3e\x2a\x40\x61\xa6\x5a\x3d\xd3\x3b\x4e\x07\x5a\x62\x29\x0a\x11\x16\x0d\xdf\xfb\xaf\x47\x8a\xca\xc2\x54\x83\xcb\xe4\x81\xca\x79\xd7\xc2\x31\x37\x2c\x7e\xf6\x6a\x7b\x3f\xb3\x4e\x93\xd5\x37\x9b\x43\xb0\x7d\xcf\x57\xa7\xc0\x0b\x42\x63\xa9\x5f\xec\x17\x6b\x81\xba\x34\xc4\xbe\xaa\x71\x4f\xa3\xf4\xcf\xcd\xf9\xca\xc3\xf1\x6b\xc4\x7a\x16\x01\xe6\xaa\xc1\xa3\x0f\xa3\x04\x1b\xcb\x96\xfe\xe2\x51\x3b\x44\x74\x8c\x5e\xe6\x77\xde\x9a\x81\xa2\x19\x59\x9d\x84\xda\x28\x3c\xb3\x81\x8d\x5e\x11\xf1\xd0\xad\xa8\xd2\x61\x94\x63\x14\x6e\x8d\x53\xc6\xad\xf5\xbf\x32\x35\xfb\xf8\xba\xf2\xe8\xaf\x1e\x46\x0e\x0c\x09\xcf\xff\x5a\x13\xfa\x3f\x92\x27\xd5\x70\xfd\xb9\x78\x32\x1e\x7f\xf7\x30\xc3\xdf\xae\x3c\xf0\xad\x6c\xdf\xb5\xd8\x67\xa3\x62\x49\x59\xaa\x0e\x67\xd7\xab\xe9\x57\x68\xeb\xd6\x11\x63\x40\xed\xae\xf3\xf4\x36\x10\xa5\x51\x54\xb7\xc0\xfa\x01\x6b\x3d\xae\x6e\x79\x4f\x27\xc8\xe9\xe4\x4e\x6c\x15\x39\xa9\x5d\x59\x14\xe4\x39\x72\x39\xe8\x40\x12\xa4\x98\x0a\x02\xfa\x16\xd9\x4b\xbf\x33\x19\x95\xcf\xfa\xdb\x70\x77\x4c\x75\xde\xb6\xd9\x07\xe9\x1e\x9c\x72\x03\x24\x45\xd4\x50\x7f\xca\x63\x71\x6b\xf5\xb1\x90\x11\x46\x61\x6e\x46\x11\xd7\x7e\xe1\x1e\x8c\x9d\xb7\xb8\x8a\x1d\x27\x26\x32\xc5\x91\x1e\x10\x1c\x77\x22\x06\x30\x2b\x6a\xec\x28\x76\xfa\xd4\x91\xa6\x04\xb1\xbb\xe4\x58\xf2\xd2\x8a\xd5\xd2\x6a\x59\x5e\xb2\x14\x9e\xda\xf3\xc1\xe0\xb1\x06\x41\x6e\x1d\xf6\xd8\xad\x91\xf6\x3b\x4c\x62\xcc\x3f\x03\xe1\x14\x04\x60\x5e\x56\xab\x59\x46\x42\x1b\x53\xe0\x05\x22\xe7\x96\xcf\x62\x9d\xd7\x5c\xd2\x52\x13\x23\x37\x87\x2d\x0d\x91\xb2\x29\x44\xa2\xd4\xb1\x59\x8b\xaf\x43\x19\xd6\x77\x27\xa0\x83\x75\xbb\xb3\x88\xca\xa4\x27\x6b\x4c\x75\x69\x15\x30\xfb\x16\xce\xdc\xe0\x1e\x27\x03\x98\x39\x1c\xe3\xd3\x8f\x95\xe3\x57\xab\xec\x62\x10\xfd\x5c\xb1\xcb\x30\x94\xd1\xa1\xd1\x26\x7b\xf4\xd9\xb9\x59\xd6\xd3\x33\x7a\xa6\x35\x36\x39\xc2\x1a\x6f\x37\xb7\x90\x5f\x01\xb9\x2e\x58\xd2\x67\xf3\x1b\xb6\x79\x10\x16\x99\xb1\x0d\xfb\x86\x97\x55\x29\xd6\x9d\x1e\xe4\xbc\x64\x7e\xb4\xc2\xca\x7d\xcf\x83\x42\xb2\xf7\x11\x67\x07\x4e\x74\xe3\x72\x2c\xb5\x3c\x34\x31\x7c\x9e\x5a\x91\xeb\x5e\xca\x24\xde\x61\x6f\x47\x34\x8f\xa6\x39\xdd\x64\x8f\xa5\x2b\x8b\x59\x48\x77\x39\xeb\x4d\x4e\x65\xb0\x40\x7e\xb7\xda\x7e\x59\x31\xbc\x96\x16\x48\x84\xad\xd5\x80\xa2\x32\xf1\x37\xcf\xdb\xf3\x75\x1f\x32\x3b\x9f\x3f\x7b\x73\xca\xdf\x94\xfa\x9a\x64\x64\x87\x18\xcd\x63\xdd\x26\x78\x38\x9d\xd1\x71\x10\x18\x0f\x9b\x40\x6a\x8a\xb8\x33\xc0\xb9\x1e\x3d\x73\x6d\xd9\x61\xef\xed\xbd\x6e\x36\xec\x3f\x93\xe7\xe6\xac\x11\x06\x3d\x8f\x9e\x4d\xba\x01\x3a\x93\x0d\xbe\x33\xa2\x3a\x23\x5e\x9c\x99\x0a\xad\xe9\xc9\xdc\xe9\x25\x29\xe3\x88\x1a\xad\xf9\xa6\x55\x84\x67\x2f\x9a\x8d\x5b\xd3\x74\x64\x52\x4e\x55\xcb\x4d\x14\x5d\xf5\xb6\x64\xaa\x77\x28\x3e\x61\x53\x83\xc6\xce\x8c\x27\x68\x6c\x27\x65\xa1\xd9\xb7\xc7\xee\x6b\xa5\x49\xe6\x14\x84\xf0\x87\xc5\x1e\xe7\x83\x2f\x00\x61\xcc\x4e\x18\xb2\x35\x17\x87\xf5\x7c\xf6\x79\x2a\x3c\xea\x8a\x01\x78\xa1\x95\xa2\x4c\x1c\xbc\x92\x11\x0c\x63\x6b\x9b\x35\x60\x1a\x35\x7f\x37\x51\xf7\x36\x91\x17\x9a\x6f\xd2\x6a\xd1\x04\xf8\x29\xb8\x17\xd2\x17\xe0\x44\x8e\x1e\x4e\x96\x2c\x59\xa8\xa1\x36\xc5\xa8\xb0\x57\x65\x62\x37\xc4\x14\x04\x07\x04\xd2\x76\x4c\xef\x15\x56\x03\xee\x55\x2e\xa5\xfd\x87\xf6\x49\xeb\xf6\x4f\xd6\xe7\x18\x83\x7f\xf0\x24\xff\xae\x39\xc0\x63\x5b\x06\x7a\x1d\x34\x68\x48\xdb\x1b\x85\x1e\xda\x65\x5e\x5e\x91\x13\x41\x0c\x26\xf7\xea\x7e\x1d\x50\x87\x8f\x11\x29\x2b\x11\x6c\xd9\x76\x0b\x44\xf3\x83\x72\xd7\x68\x74\x47\x9a\x3b\xfe\xa4\xd9\x80\x51\x47\x09\x77\x15\xfb\x55\xca\xc8\x79\xbe\xef\xa2\x8a\x37\xb1\x5a\xf6\x30\xb0\x41\x2f\x49\x12\x43\xbe\xa9\xa2\x30\xe4\xc9\x73\xb4\xf9\x0e\xee\x4b\x7e\x00\x8b\x57\xb6\x2e\xd1\x55\x81\x82\x3a\x23\x88\xc0\x82\x37\xe0\x84\x9a\x74\x49\xcf\xa2\xe1\xcd\x2d\x58\x9a\x23\x40\x63\x90\xa6\x3a\xa9\xd6\xe0\xe9\x38\x1f\x2f\x7c\x05\x4b\x52\xcc\x87\x11\xe5\xb9\xce\xab\x88\x76\x27\x4f\x0a\x67\x3b\xe7\x16\x1b\xbd\x96\xd6\x05\x8e\x9a\x8e\x1d\x6e\xa1\xdf\x31\x13\xaf\xef\x75\x53\x5f\xd1\xf8\x13\xa8\x61\x94\x85\x9a\xe2\x21\x92\xeb\x90\xb0\xb3\x04\x63\x28\xc8\x15\x6c\x61\x33\xec\xb3\x26\x27\x70\xd6\xeb\x14\xce\x21\xb5\xdf\x06\x56\x36\x0b\x6c\xcc\x47\x2d\xcf\x78\x26\xda\xa1\x78\xa4\x2e\x09\x5c\x36\x16\x50\x29\x74\x62\x2e\xf0\xab\x2b\x9a\xe1\xdb\x81\x5e\x0b\xbf\x1e\x29\x52\xe2\x6e\xdf\xee\x39\x8f\x54\xa2\xd9\xb2\x56\x80\x99\x75\xac\x67\xe3\x51\xf0\xa8\x6e\x7b\xa7\x1f\xd0\xf4\xf4\x41\x34\x25\xf3\x90\x45\x93\xb9\x37\xcd\x8e\x1e\xed\xdf\x5e\x5d\x0c\x09\xc8\x06\xaa\x92\x6a\x93\xfc\x13\x39\xd2\x6b\xfb\xa4\xb5\x5c\x87\x14\x9f\x36\x23\xf3\x46\xa2\xb0\x31\xf1\x9e\xfa\x0e\xa5\x5b\x22\x80\x5a\xd0\xf7\x7b\xcd\xe7\x5e\x76\xb2\x4e\x37\x61\x89\x63\xa7\xe4\x17\x5c\xf4\xb6\x74\xfc\x38\xa9\x49\x4e\x02\x79\xa2\x28\xb1\xb8\x6b\xbb\xde\x26\x24\x5d\xdf\xfc\x9a\xc6\xb8\x9e\xe1\x8e\xed\x20\x88\x22\x34\x22\xcf\x7e\xac\xf3\x56\xb4\x10\x19\x27\x75\x01\x4e\x60\x38\x49\x28\xeb\x27\xa7\x18\x67\xac\xd3\x29\xf7\xe6\xbe\x20\x36\xac\x59\x1f\x27\x7d\x08\x01\x47\x93\x88\x88\xd1\xa4\xb7\x09\xdc\x0d\x08\x98\xad\xd3\x0f\xad\x2a\xca\xf3\xc1\xcf\x14\x22\x8e\xa5\x88\xd9\x08\x6c\xec\xdb\xcd\x47\x52\x1e\x12\xca\x89\x5f\xea\xba\x25\x47\x23\x0d\x9a\x0c\xa8\x03\x29\x26\x9f\x84\xde\x22\x7f\x02\x3a\x81\x23\x45\x61\x99\x51\xac\xc9\xcd\xe0\x23\x54\x0b\xd5\x81\xd0\x3d\x7e\x7d\x80\x1a\x87\xb7\xb0\x8b\xc3\x2a\x3f\x91\x7c\xf0\x39\x77\xfc\x68\x47\xe7\x0f\xb5\x08\xea\x24\x03\xaa\x9b\x86\x44\x98\x85\x9b\x48\x87\x12\x2f\x31\x9c\xdc\xad\xa0\xec\xb7\x8c\x51\x4b\x9c\xf1\xd4\xc9\x80\x56\xa5\xd3\x88\x55\x8e\xbd\xab\x24\x23\x3f\x6a\xbe\xa9\x44\x0b\x9e\x72\x6d\x01\xde\x0d\x08\x83\xc3\xaf\x92\x81\x55\x0f\x78\xbd\x3e\x7a\x4a\x0c\x8f\xfb\x26\x5a\x73\xe1\xda\x83\x8a\x90\x6a\xa7\xfe\xe4\x51\x29\xf4\xb8\x77\x2a\x14\x14\x40\x92\xd9\xff\xda\x89\x50\x48\x9a\xee\xc6\xba\xb7\xaa\xce\x07\xda\xfd\x0f\x65\x43\xf3\xe7\x22\x43\xe6\xfc\x7d\x45\xb3\xff\x69\x37\x44\xdb\x53\x05\xdd\xb3\x0a\x1d\x47\xb0\x2e\x50\x73\xaf\x01\x3b\x00\x3e\xc3\x3b\x1e\x85\x0a\xc4\x43\x90\x6c\x85\xfa\xdf\x8f\xa0\x38\xef\x87\x0a\x64\x98\xc5\xd2\xe1\xf4\x4c\xec\x68\xc6\xca\x1d\x45\x6a\x25\x9a\x99\x9d\xda\xfe\x33\xc4\x21\xca\x43\x4e\x49\xc4\xac\x7c\x81\x87\xb0\x7d\xde\xae\xe5\xd5\x83\x08\x4b\xc3\x42\xb5\x91\x34\x4c\x42\x71\x05\x80\xe1\x15\x86\xaf\x3d\x5c\xb2\xf0\x2e\x26\x07\x9d\x15\x12\xd2\x8c\xf6\x83\xf3\x4f\xf4\x3b\xde\x68\xae\x0e\xcd\x0f\x99\x47\xc3\xad\x23\xa3\xd1\xf2\x07\x55\xa3\x26\x36\xce\x4d\xe1\xe3\xa9\xee\x67\xaa\xae\xc7\x16\x5d\xb1\x1d\xad\x56\xfc\x7f\xec\xbd\x79\xef\xe2\xc8\xb2\x20\xfa\x55\xd0\x48\x57\xf5\x46\x0c\x78\xdf\xde\x53\xff\xe1\x1d\xe3\x05\x2f\x78\xe3\x9f\x2b\x6f\xd8\xc6\x1b\xe0\xdd\x9f\xfe\xc9\xe6\x57\x55\x7d\x4e\x77\xcf\x39\x57\xb7\x47\xea\x91\xba\xc4\x2f\xcb\x64\x46\x46\x46\xc6\x96\x11\x81\x31\x6f\x42\xce\x9c\x74\xe1\x87\xd1\xc5\x8b\x37\x4b\xc1\x3c\x5e\xa0\x72\x4c\x85\xe7\x0e\x23\xce\x0e\x36\x08\x32\x2c\xdf\x4d\xc3\x74\xf6\x26\xad\x16\xcb\x94\x96\xbe\x04\x99\x01\x37\xc3\xb1\x0b\xbd\x9f\xae\xf9\x30\x1a\xcc\x11\xf3\xc8\x97\x9a\xb7\xeb\x34\x8d\x30\x18\x0e\xcb\xd2\x0f\x91\xbc\x54\x23\xa4\xa6\x22\x49\xab\x60\x6f\x31\x36\x67\xd5\xec\xbd\x00\x24\x91\x3d\x8d\x77\x84\x63\x39\x80\xb0\xb3\x8b\xc2\xbc\x85\x82\xeb\x93\x27\x90\x71\xb6\x65\xb1\x03\x94\xfb\x0d\xfa\x96\xee\x2f\x71\xac\x6c\x4b\x3b\x3f\xee\x7e\xc8\x44\x86\x9c\xdd\x46\x30\x60\x54\x1a\x65\x50\x52\x19\x99\x8c\xe9\x80\xe8\xa2\x91\xe0\xa9\x52\x29\xcd\xc0\xef\x5e\x0a\xb8\x65\xd1\xa3\xd7\xb1\xd2\x5c\x6e\x09\x8c\xd7\x72\x12\xf7\xa0\x6e\xc9\x4d\x8c\x45\x27\xcc\xc9\x60\x33\xa7\x33\x5f\x8e\x48\xae\x74\x20\x5b\xb7\xe6\x5e\x50\xc5\x39\x75\x4a\x35\x85\x00\x1d\x67\x58\x9c\x7b\x79\x86\x4c\x3e\xb4\x1b\xe7\xd1\x3e\x0d\xdd\x61\xc8\x41\xd0\x51\xf5\x7c\x21\xc8\x67\x67\x04\xdf\xe7\x79\x51\xd2\x16\x71\xd4\x62\xba\x3c\xc4\x2e\x9f\x00\x07\xf4\x5c\x36\xbb\x81\x91\x04\xe7\x40\xbc\x0c\x5e\x7c\xbf\xc6\xa0\x71\xa7\x20\x46\xd5\xdf\xd9\xac\x2d\xa9\x7c\xbf\x54\x53\xe0\xce\xcf\x57\xc0\x79\xa7\xed\x11\x84\x1d\xab\x90\xde\xe5\x2e\xa0\xc4\x9f\xfb\x80\xb1\xec\xaf\xf6\x95\xa2\x24\xfb\xf5\x57\xf4\x06\x10\xa4\xed\x93\x0c\x78\xf2\x1d\x9a\x6f\x31\x6f\x39\x26\xe3\x3d\x4c\xcb\x14\x5e\xaa\xe1\x30\x34\x26\x45\x98\x84\x70\xf5\xc8\x03\xe9\xb3\x56\xea\x59\x44\x94\xd4\x4b\xcb\x09\xb5\x39\x4e\xb9\x59\xa0\xe9\x16\x9c\x92\x9b\x93\xd5\xb7\x05\xd5\xe3\xa2\x67\x25\x55\x58\x29\xa9\x7b\x0b\x3d\x62\x0f\x87\xf5\xad\xa4\xe0\x2a\x05\xd3\xa6\x41\x42\xe4\x7e\xbf\x00\x75\x14\x0f\xf3\xfd\x71\x4a\xee\xf8\x0b\xe6\xca\xa1\x25\x0d\xb8\xe8\x96\x37\x84\xef\x2d\x05\x07\x1f\x59\x76\xc3\xa9\xf0\x42\x7a\x24\x5b\x2a\x2c\x31\x52\x5e\x2c\x9f\x1d\x91\xbc\xf7\x2a\xf8\x86\xdc\xf7\x59\x44\x53\xef\x91\xbe\x6c\x88\x03\x55\x31\x82\x0b\xe6\x3a\x77\xe5\x9e\x08\x28\xaf\x72\xa3\x12\x92\x18\x20\xbb\xc9\x7c\x16\x45\x2f\x2c\x38\x9f\x81\x04\x09\xaf\x3d\xe1\xa6\x10\xeb\x34\xc4\x5b\x53\x4a\x33\xb3\x33\xb4\x51\x6b\xaf\xe1\x9a\x39\x6b\x4e\xe2\xec\x56\x76\xb2\x37\xec\x90\x57\xa4\x80\x70\x49\xf6\x41\x0b\xa5\xba\xc4\x4b\x12\x15\xec\x28\x68\x20\x4e\x5f\xe9\x9a\x34\x2a\x4e\x55\x55\xb1\x54\xfb\xd1\xed\xa3\x67\xc3\x9e\xb4\x04\x7d\x30\x05\xad\x26\xf5\xc3\x1f\x4c\xfd\x3a\xe7\x18\x72\x1e\xfa\xd1\x23\xe9\x67\x59\x26\x74\xc2\x44\xa6\xf0\x3e\xe1\x6f\x4f\x9a\x94\xbc\xa2\x24\xe0\x99\x23\x06\x0d\x99\x99\x1c\xf8\x53\xfc\x28\x34\x52\x1a\x83\x92\x55\xa5\xd1\x6d\xa9\xf2\xa1\x16\x19\x38\x2e\xc5\x9e\x52\x89\x11\x22\x28\x16\x51\x6e\x9a\x37\x0d\x09\x9c\xed\x23\xe4\xd4\x53\xd0\x29\x91\x2b\x0e\xc0\x97\xd3\x45\xa9\x47\x12\xc9\x4b\x06\x02\x1c\x90\x4d\x5e\x36\x62\x90\x90\xc2\x02\x17\x14\x0a\x61\xa6\x9b\x60\x0d\x3e\x3b\x3a\xfc\xce\x4d\x32\xb9\xda\x53\x95\x83\xd7\x85\x19\xdf\xf2\x4d\x6d\x5f\x6a\xb3\x90\x6a\xcb\x65\x00\xe7\xf6\x6e\x66\x33\xb2\x6d\x2a\xf2\x64\x48\xc9\x45\x75\x9b\x67\xe7\xeb\xb5\x05\x45\x7b\x49\xbb\x31\xc5\x28\x59\x4d\x75\xb1\xda\x8a\xb9\x59\x04\xb3\x47\xdc\xcb\x72\x1b\xde\xb2\xb8\x14\x2a\x9d\x8b\x2f\x6d\x26\xd2\xbd\x52\x99\x85\x79\x4f\x0a\xa6\xa6\xb5\x19\x86\x70\x44\xbf\x79\x6f\x2b\x7c\x1b\xf8\x10\x65\x10\xe5\x2d\xe4\x5d\xe7\x4e\xb3\x82\x50\xc6\x52\x9c\x18\x39\x89\xbd\xc7\xbd\xdf\xcf\x08\x4d\x8b\x36\x42\x48\x1a\x73\xee\x9a\x3f\xf5\x01\x5d\x59\x57\x95\x7f\x2d\xa3\xab\x7e\xf5\xdc\xda\xe2\x2b\x7c\xad\x7c\x1c\xc4\x82\x7d\x96\xdd\xae\x8c\x26\x9b\x1c\xfd\xd4\xde\xae\x64\xd2\x68\xcd\x33\xf6\x2d\xae\xd8\x54\xd1\x72\x54\x95\xb1\xfb\x5e\xd0\xe2\x1e\x09\x85\x01\x3a\x43\xbc\x77\xe1\x58\x13\x3a\x9f\x2d\xf5\x3a\x3e\x5f\xb6\x8e\x6b\x39\xfb\x4c\x20\xf0\xf6\x58\x90\xec\x81\xa9\x15\x92\x5b\x73\x58\x22\xc4\xa3\xbe\xef\x23\x0c\x79\x54\x5c\xa8\x3d\x73\x2a\x09\xf7\xb8\xd0\x45\x79\x9b\x04\x14\x48\x85\xae\xb6\x68\x21\x1e\x8f\x8b\xe5\xc9\x45\x26\x75\xc0\x1b\x42\xf7\x18\x84\xbd\x98\x57\xc5\xd1\xe4\xe9\xf9\x92\x83\x34\xc3\x10\x2f\x68\x9e\x61\xf9\x94\xc2\x64\x5f\xd4\xdc\x53\xa0\x33\x3d\x08\x61\x6e\x04\xaf\xf2\x60\xca\x44\x59\x69\x17\x6e\x49\x74\x26\xbd\x95\x32\xd5\xd8\xae\xf5\xac\x1c\x2d\x7e\x4a\x36\x79\xdd\x3f\x02\xb5\x9d\xd5\x80\x43\x55\x2e\xba\x39\xc1\x5e\xcb\xce\xaa\x06\x82\x23\x58\xe3\x0e\x5c\x6b\xc8\x6c\xa4\xf1\xc9\xbd\x05\xe9\x5e\x59\x7c\xfd\xda\x54\x12\xdd\x5d\xc1\xeb\xc9\xe9\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\x16\xe7\x05\x8a\x7d\x96\xa2\x26\x7d\x12\xec\xac\xba\x0f\x2f\xe4\x01\x21\x68\xe0\x35\x64\x18\xef\xa5\x6b\xad\x0a\x97\x4b\x33\xd8\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\x79\x15\x63\xce\x9a\x01\x17\xe4\xab\x3b\xaa\x58\xb8\x49\xb6\x03\x04\x31\xd5\x7d\xb1\xc6\x42\x8f\x2a\x02\x3d\x37\x14\x9f\x83\xe2\x2d\xad\x8a\x91\x34\xd8\x4b\xd0\x90\x17\x2f\x0a\x16\x00\x1b\xac\x5b\xad\xc7\xf5\x13\xa1\x9f\x2f\x86\x51\x0a\xf7\xcc\x83\x6c\x4e\xd0\xd6\x12\x4a\x19\xab\x28\x06\xc4\x83\xf9\xa5\x60\xb8\x8c\xd2\x9e\x76\x9a\xdb\xc9\xa3\x21\x1b\xad\x3f\x8f\x73\x0d\xfa\x3a\xcd\x74\x35\x06\xd9\xbe\x20\xe4\x83\x88\xcc\x8c\xc8\x6a\xb7\xa2\xe7\xba\x08\x50\xdd\xfd\xcd\x90\x90\xcb\xdb\x7f\x32\x01\x6d\xb2\x72\x7f\x2f\x10\x06\xf3\xa4\xdc\x9d\xb3\x5c\xc1\x2e\xdc\x93\xdc\x0b\x77\xe1\x74\xda\xcb\xb9\x6c\xbd\x5c\xd9\x56\xc8\x3b\x0b\x68\x4b\x2d\x96\x3a\x53\x2d\x7b\x18\x8d\x6f\x0f\xb9\xe6\x40\xf6\xcc\x45\x6a\x33\xbb\xa0\xf5\xf2\x7a\xb5\x3b\x31\xc2\x48\xbc\x33\x89\xe6\x20\xfe\xad\xd9\x5a\x70\x9f\x64\x46\x4b\x86\xe0\x39\xf6\x38\xa6\x3d\x79\x03\x15\x5e\x9e\x44\xef\x4d\x35\xc6\x9d\x91\xd1\x91\x48\xb7\x78\x33\xc4\x53\x45\x12\xa4\x17\x0e\xed\xed\x97\xe8\x06\x42\x1c\xbd\x9d\x0e\x28\x2b\xba\x77\x1f\x74\x0e\x07\xb9\x2a\x8c\xd5\xc5\xef\xa5\x33\xa0\xe1\x2a\x4c\x0e\xa3\xa4\xd2\x6a\xa3\x71\x73\x8a\xbe\x23\x9b\xfa\x33\x9d\x42\x1e\xfd\xc5\x3e\x66\xcb\xcc\x5f\xf9\x04\xe1\xc7\x77\x7b\xe3\x77\x40\x84\x8a\xf6\xcc\x61\x7a\x32\x04\x39\x28\x8b\xf3\xbb\xc9\x24\x36\xf7\x0b\x4f\x0f\x52\xef\x3d\x11\x24\x77\x47\x65\x94\x14\x39\x66\xa9\x8c\x44\x57\xd4\xcc\xbe\x70\xda\x64\x60\x51\xce\x17\x67\xe7\xc5\x75\x67\xb1\x52\xdd\x37\x4b\x5f\xcd\x30\x86\x93\xa8\xb1\xb0\x1e\x09\x9a\xa1\x4a\x96\x76\xe8\xa9\xed\x96\x64\x3d\x97\xcb\x4c\x42\x3d\x85\x88\xe0\x37\xe6\x2b\x24\xa4\x48\xbc\xc2\xa7\x99\x42\x23\x3d\xd0\xc7\x53\x75\xaa\xf5\xea\x2e\xba\x80\xdb\x0f\x7b\xe5\x39\x8e\x71\x9d\x98\x3e\x33\x11\x7a\xe2\xca\xe0\x78\xf1\xfd\x2c\xf2\xa6\x39\x2a\x44\x07\xba\xc7\x61\x1d\xf6\x6a\xeb\x45\x45\xf9\xd2\xcd\xb3\x31\x09\xaa\xbc\xa0\xe6\xc4\xb1\x9d\x73\x41\x5b\x64\x2a\xcd\x87\xdb\x30\xa0\xe0\x3f\x4a\x43\xe7\x79\x26\x4f\xd8\x6c\x94\x59\x53\x54\x27\xac\x57\xba\x40\x6e\x21\x1d\x4b\x72\x52\x92\x4b\x31\x00\xfc\xc2\x53\x3d\xbf\x2b\xaf\x3c\x57\xb6\xf5\x08\x54\xaa\x97\x31\xe7\xe8\x35\x59\x32\x3e\x94\xd1\x33\x40\x75\xfe\xc9\x36\x8d\x3d\x4b\xaf\x16\x53\xf1\x4c\x84\x1a\x98\xb5\xc7\x17\x0d\x52\x50\x24\x44\xbe\x72\x07\xda\xc7\x12\x79\x04\xc6\xe7\x86\xd4\x3c\x24\x8a\x20\x28\xf6\xea\x9b\xe8\x63\xbc\x32\xf7\xfd\x9b\x10\xe9\x31\x03\xe9\x89\xcd\x15\xfc\xac\x5e\x01\x10\x1d\x0c\x82\xea\xc9\x40\x82\x2f\x00\x71\x5e\x52\x9c\x6a\x70\xb1\x21\x93\x71\x8e\xec\x20\xeb\x98\x27\xcd\x65\x27\x59\xa9\x65\x20\x71\xc2\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\x9e\xc9\x77\xdc\x8f\xba\x05\x8c\x31\x90\x64\x55\x8e\x14\xe3\x0b\x5d\xae\xa7\xdc\xb5\x53\xef\xb9\xe7\x7b\x85\x14\x06\x6d\x10\x4a\xcc\xac\xd1\x89\xb6\x48\x3c\x9f\x25\xb8\xf0\x91\x1a\x54\x07\x94\x64\xe6\xf7\xc5\xa8\x82\x3a\x8a\x73\x52\x02\xe5\xe8\x81\xd8\x58\xde\xd3\x30\x35\xd1\x49\x29\xb3\xf6\xe9\xcd\x4b\xc1\xbc\x94\x5d\x90\x8a\x30\x8f\x4a\x63\x21\x04\x46\x6a\xb1\x78\xe9\x4b\x20\x95\x6b\x60\x4c\x4a\x1d\xd6\x6b\x0e\x56\x8b\x58\x9b\x9e\x63\xd9\x67\x41\x91\x74\x9b\xeb\xe5\x36\x30\x92\x25\x68\x3c\x33\xd5\x6d\xbf\x70\x88\xe8\xa1\xc3\x9d\x6b\xdb\x65\x79\xd1\x3d\xf8\x28\xce\x06\x97\xc4\xac\x18\x32\x38\xed\xa6\x18\xfa\xf4\x43\xbd\xd9\x6b\xa2\xa3\xc7\xd7\x94\xe6\xe9\x97\xf1\x22\x40\x7d\xee\x24\xe5\xcf\xfd\x2e\x7e\xde\x36\x7f\x2d\x7b\x7d\xfc\xfc\x58\xbc\x68\xbb\xb7\x0d\xf2\xf6\xf4\x06\x0a\xec\x15\x9e\x97\x58\xf7\x9f\x62\xf1\x6c\xed\x73\x43\xc3\x2f\xa8\x51\x1e\xd7\x38\x17\x73\x89\xc5\xa2\xde\x3b\x95\xd3\x40\x31\xfc\xe5\x6d\x75\xd7\x81\xa9\x8d\xc1\x7c\x5b\xb4\xd4\x26\x0f\xf6\x5d\xbe\x9e\xad\x6d\xbe\xe0\x8c\x3d\x6b\xc6\xfe\xaa\x29\x15\xd6\x47\xc0\x84\xa8\xd5\x72\xce\x10\xb4\xe2\xb4\x7a\x18\x6a\x6d\xb9\xf0\xa8\x28\x5e\xc6\x89\xdc\x77\x94\x67\x14\xf7\x1a\x74\x78\xd0\xc7\x00\xe2\xb6\x2f\x4e\xd5\x3e\x1e\x2e\x59\x17\x23\x3a\x15\x01\xd3\xa8\xdd\x32\xa2\x76\x03\xd5\xef\x34\xbb\xf2\x00\x21\xea\x80\xa1\xd4\x08\x80\x3c\x63\x81\x69\xa6\xf3\x52\x91\xd3\xf2\x34\xb9\x87\xc8\xc3\x81\x73\x42\x9d\xeb\x2b\xae\x1b\xdb\x4f\x01\xaf\xe0\xb3\x6a\xde\xb3\x13\xc2\x65\x34\xd6\xa9\x4b\x2c\x34\xe5\x90\x62\xea\x84\x08\x13\x65\x55\x27\xf0\x2c\xa5\x04\x75\x6b\x90\x07\x2a\xd2\x9c\x2a\x35\xc5\xf9\x2a\x77\x8f\xf0\x4e\xcb\x9e\x8d\xfa\x00\xac\x0d\xd6\x7d\x3e\x11\xd8\x55\xb8\x4c\x01\xc5\x56\x6f\xd0\xab\x4b\x7d\x55\xea\xe4\x62\xe0\xa3\xa6\x72\x6d\x23\x78\x38\xcd\x97\x2f\xa3\xd4\x1c\x48\x6e\x2f\xbd\x36\x5a\x00\x2d\x0a\x0f\xde\x96\xb8\xac\xaa\xb1\x3d\xc0\xa9\x2a\x84\x03\x54\x9e\x32\xcd\x48\x2f\x82\x2c\xb5\xa3\x7e\x7e\xe3\xea\xa3\x9c\x04\x1d\x69\x1d\x10\x4d\x03\x9d\x30\x17\x55\x4f\xf0\x69\x70\x55\x28\xd5\x6c\x46\x85\x6d\xd9\x2f\x99\xa0\x47\x8c\x34\x13\x9f\x59\x0a\x53\x67\x24\xe5\x4a\x45\xc9\x4b\x57\x8b\x39\x24\x2d\x06\x49\xe2\xcc\x8c\xa3\x66\x31\x81\x2b\xd6\x01\x1d\xf4\x24\x78\x3d\x3b\x5d\x31\xae\x1c\x48\x6e\x41\x5a\xa9\xa0\x5b\x10\x11\x82\x92\x9b\x18\xd5\xb0\x3a\x8a\x31\x19\x35\xd3\xea\xa8\xbf\x10\xf1\x6c\xc3\x64\x44\x75\xf5\x9d\x64\x01\x03\xbc\x75\x26\x2a\x4a\x55\x62\x58\x0f\x92\xd6\x15\xf3\x44\x10\x30\xe3\x46\x69\x2e\x5c\xb8\xfb\x9d\x1d\x80\x8e\x3c\x51\xdd\x05\x1c\x10\xf3\xe1\x10\xce\xab\x48\x12\x4f\x29\x17\xee\x3e\xf8\x8f\x07\x49\xf6\x5e\x56\xa2\xe7\x51\x6a\xdf\xfe\x54\x29\x3e\xa0\x42\xa9\x1f\x95\xd2\x20\xf2\xd4\xe3\x76\xd7\xf4\xb7\xc5\x72\x08\x60\xa4\xca\x9c\xb8\x57\x9a\x73\xf0\xd1\xa5\xe8\xf7\x2c\x45\x6c\xc1\x80\x3d\x44\xbf\x80\x86\xd5\xfb\xaa\xec\xef\x8d\x40\xc0\x83\x94\x25\x81\xc2\xbd\xd1\x91\x55\xa4\xcb\xeb\xed\xd7\xb6\x42\x43\xa8\x6e\x35\xaf\xa7\x75\xe6\x69\x3b\x2f\x6f\x6f\x8e\x20\xac\x01\x51\xe4\x7d\x24\x81\x7b\x26\x21\x23\x3a\x0c\x2b\xfa\xf2\x6e\x42\x30\x48\x3b\x0e\xa5\x20\xc5\xbf\x17\xcd\x6b\xa8\xe7\x9b\xd2\xba\x66\x41\x03\x69\x31\xd2\x8c\x82\x5a\x88\x42\x90\x9e\x3f\xff\x99\xe7\xf1\x23\x18\x82\xbf\x98\x81\x7f\x7f\x78\xcd\x93\xb4\xc1\x4f\x66\x5c\x6b\xf9\x85\x9f\x93\xa7\x31\x67\x46\x13\x9a\x8c\x55\x3a\x52\x63\xb2\x0c\xaf\x5f\xe9\x87\xd1\x5a\x7c\x9d\xf0\x7b\xba\x26\x05\x75\x35\x74\x45\x6b\x8c\xb8\x97\x68\x1e\x79\x35\x4f\x59\x3b\xd3\x92\xf4\x7c\xd2\xf0\xe3\x7d\x31\x29\x24\x08\x70\x40\x23\xe7\x5b\x6f\x4f\xf3\x54\xbc\xbd\x37\x72\xbf\x57\x4b\xb4\x84\x57\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\xb6\xab\x64\xa6\xee\x3a\x93\x2c\x7c\xea\x3a\x42\xef\x2b\xf1\x3c\x94\xba\x18\xa8\x3e\x7a\x2f\xa1\xc0\xb4\xf6\xd4\xf3\xa5\x63\x7c\x49\x17\x55\x54\x17\xb5\x39\xf6\x97\xbd\x36\x77\x58\x0f\xf0\x57\xff\x3e\x3f\x28\xf7\xfd\xbc\xd5\xd5\x73\xaa\x61\xe0\x52\x40\xd6\x58\x03\xe2\xd0\xd5\x27\xac\x40\xaf\x4a\x9f\xa0\x85\x76\x9f\x1a\xa1\x79\xbe\x4d\x63\x80\xae\xcb\x25\x24\x23\x5a\xea\x91\xfd\x8d\x23\x1a\x0e\x38\x55\x84\xd7\x4f\xcb\xcb\xb4\x35\xae\x8b\x8b\x5e\xc9\xaf\x95\x8b\x75\xc2\x14\x25\x8c\x57\xd6\x5e\x6a\x5c\xe9\x8b\x69\xa9\x1d\xdc\x88\xc9\x62\x9f\xcf\xe7\xb7\x4c\xc5\x82\x1b\xf3\x27\x42\x2a\xd0\x98\x81\x29\x25\xe7\xad\xc4\xe6\xcf\x5e\x4c\x00\x31\x7d\x45\x94\x3d\x94\x0f\x25\x7b\x7a\x93\x1a\xbf\xf4\x9d\x77\x65\x86\xf0\xac\xeb\x56\x7c\x01\xe8\x13\x36\xce\x2d\x9b\x8d\x2a\x00\x9d\x16\x56\x2c\x2b\x7a\xb9\xbc\xe5\xa9\x87\x13\xb6\x8f\xf1\x1b\x7c\x2e\x12\x58\x1d\xaf\xd9\xd3\xf6\x14\x5c\xab\xe1\x1b\xed\x08\xd7\x52\x1b\x09\x30\x94\xc1\xdc\xac\x45\xfa\x45\xbd\xc6\x53\x77\xa9\xae\xe6\xb3\x9d\x20\xad\x3d\xcd\xb2\xe9\xd4\x9a\x5e\x37\x6a\x23\x53\x45\x04\x33\x8f\x90\x43\x87\x02\x3b\x8b\x0e\xa6\x15\x4c\xc3\xeb\x2a\x2a\x08\x35\xdb\x25\x67\xc1\xbd\x58\x68\xdd\x9d\xf8\xfb\x33\x33\x66\x39\x10\xae\xae\xa0\x8c\x04\x88\xd2\x67\x18\xbf\x09\x13\x70\xe3\xf9\x1c\xf1\x67\x1f\xbc\x40\x5c\xf5\x46\x79\xf9\x6a\x9f\x68\x32\xb3\x6b\x0b\x6f\x73\x09\xe4\xf8\x93\xe2\x37\xe9\x3e\x84\x49\x93\x35\x7b\xcd\x33\x81\xdc\xb0\x9f\xba\xcd\x1b\x7b\xcd\xc9\x3a\x5c\x69\xe2\xfa\x31\xed\x45\xcf\x4f\x39\x4b\x30\xeb\x17\x45\xf0\x31\xfc\xf4\xac\xd2\xcb\x6c\x2b\x11\xb3\xc9\x8f\xb0\x56\x2e\x35\x4f\xc5\x38\x51\x31\xe1\xab\x3a\xde\x6f\x8e\x4e\x4b\xf9\xbe\xe9\x44\xcd\x9d\xa1\x3b\x7f\xb3\xe5\xa4\x41\x5f\x11\x3a\xb7\xd2\x5e\x20\x9d\xa2\x55\xa4\xf3\xdd\x8f\x38\xca\xf0\x53\x06\xe0\x34\x5d\x7d\x76\x2e\x53\xb6\x35\x23\x59\x24\x3e\x55\x9c\x7a\x65\x1a\x40\x77\x63\x50\x61\x70\xe7\x76\x8f\xf9\xf0\x7c\xfd\x3c\x2f\x97\xc6\x4e\xd2\x52\x0e\x54\xdc\xfd\xa9\xf7\xae\x3c\x9e\x49\xfa\xbf\xbe\x5f\xfe\xc5\x6e\xbd\xff\x79\x9b\x5b\x6b\x93\x65\xbf\x3d\xc5\xae\x45\xe3\x4a\x7d\x16\xee\x64\x36\x4f\xf1\xac\x69\x61\x3e\x66\x05\xd4\x49\x5d\x28\x76\xde\xe9\x0d\x66\xd1\x58\x0d\xe9\x25\x76\xcb\x18\x67\x7a\x34\x6a\xbc\xbe\xea\x4c\x9e\x47\x6e\x72\x4f\x0a\xe9\xa5\x64\xa1\x42\x6a\xbc\x8e\x45\x1e\xfa\x3d\x8e\x00\x52\xb7\xa5\xe7\x52\x30\x2a\x31\xde\xf7\x77\x20\x6b\xbb\x16\x46\xfd\x68\xe9\x93\xb7\x68\x47\x60\xd5\x30\xa5\x7f\xa5\x7d\x7a\x9f\x93\x6d\x18\x7b\x1d\xbd\x3c\xa4\xab\xd9\xbd\x10\xaa\x78\x13\x48\x0b\x88\x6f\x8a\xbb\xda\xbe\x7e\x49\x82\x6a\x1c\xfc\xfa\x14\xbf\x63\x13\xb4\x6a\x2e\x09\x7b\x36\x6c\xc7\xb3\xf8\x7a\x7a\x7b\xfb\x4e\xc1\xa7\x57\x45\x64\x8b\x40\x8b\x00\x7a\x4d\xb5\x37\xd4\xb3\x23\x7f\x06\xbb\x77\xc4\xb0\xa4\x0d\xca\x21\x04\xe8\x46\x71\xea\xa8\xf3\x64\x29\xb5\x82\x5f\x99\xbd\x0f\x2f\xb4\xa4\x5e\xce\x8c\xa8\x78\x55\xd7\x86\x3c\xed\x33\xed\x44\x9e\xea\x17\x2b\xca\x8e\x15\xd1\x1e\xd9\x9f\xee\x18\xff\x7c\x55\xa2\x37\x40\xa4\x73\xc1\x1d\x8e\x4f\x40\xdd\x6b\x65\x9a\xd1\xc8\x3d\x4d\xa7\x79\x10\x56\xbe\xa0\x69\xe7\x2b\x67\xc0\xa6\x2d\x44\xe4\xfe\x46\x89\xe0\x45\x37\x51\x5d\xf6\xc7\x41\x0e\xde\x39\xa8\xd2\x69\xee\x03\x17\x43\x64\xe9\xe0\x91\xa9\x9a\x89\xd6\xdc\x4d\x0d\xa4\xfa\x2d\x33\x62\x49\x80\x96\xae\x5a\x51\x54\x40\x9a\x21\x22\x1e\xc0\xd2\xae\xc2\x23\x40\x4c\xbb\x0e\x96\x99\xa6\x23\x9d\xa7\x8b\xab\x15\xed\x5b\x87\xa8\x56\x48\xd5\xd7\x8b\x4e\x42\x5b\xf4\x4f\xaa\x84\x77\xc9\x0b\xa4\xa9\xe6\xea\xd0\xd9\xab\x87\xdb\x7b\xe8\xfb\x8f\x56\x21\x4a\xf6\x86\xe0\x24\x92\xd2\x04\x78\x45\xae\x32\x01\x30\x28\xa3\x35\x17\x10\x06\xc5\x91\xa1\xae\xcf\xf1\x4e\x2f\xa4\x92\xaa\x9d\x5b\x03\x5a\xe1\x90\xfc\x29\x6d\x18\x12\x8a\x88\xda\x1f\xd9\x99\xb9\x95\xbc\x53\x9c\xa2\x97\x7a\x95\x85\xba\xa8\x92\xec\x7c\xbd\xe8\x03\x7f\x67\x6b\x39\x07\xef\xf4\x4c\x73\x67\xf9\xee\xb1\x40\x46\x22\xd7\xe0\x76\x3d\x3f\x82\x00\x2b\x69\x4d\x79\x5e\x84\x17\xed\x75\x25\x4f\x37\x6f\x7a\xbc\x50\x3d\xd6\xce\x57\xcc\x9e\x94\xbb\x0d\x26\x48\x03\x09\x6a\x0f\x4d\x68\x4f\x5c\x38\xff\x05\xc2\x8c\x4c\xab\xb4\x63\xbd\x2d\x4d\x79\xcb\x90\x9a\x29\xfa\x83\xac\x34\x01\x1c\x84\x6a\xcf\x42\xb7\x61\x94\x99\xd1\xf3\x78\x94\x16\x6b\xc8\xa5\x69\x2b\x58\x78\x6b\xb4\x5d\x84\x59\x6c\x4b\x4d\xce\x70\x03\xd1\x2f\xb4\xd5\xfb\xf7\x60\xf8\x96\xa9\x8c\x65\x66\x9a\x78\x65\x05\xfe\x9c\x83\x6e\xf9\xa4\xcf\x6f\xc1\x9c\x90\xa6\xcf\x30\xa0\x54\x3b\xac\x1c\x48\x46\x19\xbd\x27\xa8\xa2\xa5\xf5\xf4\x15\x88\x48\xe0\x5e\xc6\x46\x1d\x2f\x1f\x40\x04\xdf\xf4\x1a\x36\xa5\xbd\x7f\x25\xef\xdc\xf0\x6a\xe6\x24\x75\x94\xf9\x2e\x62\x05\x23\x07\x86\x71\xb9\x0f\x02\xfc\x54\xa2\x7d\x7e\xa7\x69\x26\x37\x4e\x88\xce\x47\x50\x0e\xfc\xa9\xae\xe2\x2f\x96\x9e\xcf\xe7\xa7\x23\x64\xa0\xcb\x43\xea\xa5\xd2\x86\xd0\xc2\xb2\x0f\x3c\x86\x86\x1e\xfd\xf9\xc7\x8d\x40\x72\x62\x32\x1f\xee\xca\x98\x65\xf2\x9b\x1b\x3f\xc3\x07\x98\x13\x44\x0f\x48\x39\xf3\xbc\x71\x60\xee\x2c\x8e\xa6\xf2\xd0\x68\xc0\x4e\x13\xd8\x19\x1e\x55\xce\x35\x29\x30\xdb\x47\x9e\x6f\x7f\x29\x0b\xe9\x41\xee\x25\x6e\x42\x2f\x75\xd6\x45\x22\x54\xc6\x22\x9f\x26\x22\xd4\x86\xb5\x8a\x27\x1c\x98\xfb\xae\x39\xf8\x95\x8d\xaf\xef\x43\xd7\x01\x7d\x8b\xcc\xa5\x53\x8a\x27\x22\x34\xc6\x62\x4b\x49\x85\x50\x84\xf0\xb9\x94\x84\x4c\xb3\x59\x86\x0b\x91\x73\x29\x71\x76\xaf\xce\xd0\x43\xe5\xf8\x49\xe2\x7c\x58\x79\xf0\xa0\x76\xf5\x61\xd5\x1a\x53\xf5\x41\x4f\x6a\x4e\x8e\xeb\x9f\x96\x83\x93\xc6\x35\x90\xf6\x68\x66\x6d\xa6\x53\x89\xfd\xfa\x7b\xa0\xa9\x7e\x3a\x17\xb7\xc7\xd3\x32\x79\xff\x07\x3d\x51\x65\x56\xba\x75\x6e\xe2\x93\x39\x5e\x72\x72\x88\x91\x18\x51\xea\x68\x51\x2a\x6a\xbe\xcd\xe4\x74\xb9\x16\x98\xb2\xd0\xb3\xb2\x48\xb3\xe2\x9d\x8b\x5b\x0e\x2d\x89\x8b\x81\xbe\x97\x76\x61\xad\x3e\x7e\x85\x97\xbf\x79\xda\x23\xaa\xca\x31\x16\xcb\x21\xcc\x99\xf9\x26\xfa\xb8\xef\x9e\x87\xd8\x33\x28\x29\x97\x7e\xf2\x40\x84\xc6\x5f\xaf\x19\xd6\x6a\xff\xc5\x93\xde\x87\xa9\x4e\x41\xb2\x2c\x62\xc9\x49\x79\xd0\x83\x94\x33\x68\xe8\x4e\x7d\xb4\x3c\xd1\xd0\x63\xb4\xeb\x15\xcc\x83\x93\x09\x46\x5c\x33\x28\x30\xb6\x28\xd5\x87\x57\xca\x26\x4f\x0a\xf5\x3d\x7a\x50\x2d\x74\x54\x60\xa8\x53\xe6\x9f\x6b\x46\x88\x69\xdd\x5c\x9f\x92\xaa\x0c\x8c\x4f\x34\xae\xcc\x54\x1f\xcd\x3f\xe4\xff\x08\x61\x70\x48\x44\x61\x54\x16\xbe\x57\x59\x6a\x71\x4e\xe5\x78\xb3\x28\xeb\xe6\x69\x43\xec\x9d\x1f\xab\x2e\xdd\x72\x35\x97\x4e\x59\x17\x71\x4f\x2e\xaa\x9c\x2c\x16\xa9\xd9\x11\xa9\x21\xe4\xc0\xdc\xf8\xd0\x9f\xda\x62\x36\xc4\x22\xb5\x04\x22\x35\x4a\xbc\x76\xd5\x72\xba\x71\xe0\xb2\xbf\x89\x14\x12\xcd\xc5\x67\x3e\x0f\x69\x97\xa2\xec\x23\xc4\xcc\xc2\x4a\x2b\x2d\xdb\xa0\xa4\x55\x57\x58\xec\x19\xb8\x06\x6e\xda\x06\x76\xe1\x7c\xcc\x00\x35\x51\xbd\xf2\xa8\x7a\x15\x04\xf5\x5a\x72\xe6\xa3\xe4\x34\xd0\x61\x8c\xab\x8f\x18\xd7\x02\x54\xaf\xfc\xaf\xf0\x99\x83\x8f\x38\xdd\xcd\xc5\xc0\x5f\xe1\x2b\xfe\x11\x9f\xf9\x2f\xf1\xe9\x39\x4d\xae\xf2\xb9\xda\x20\x6e\x8a\xce\x1c\x78\xb7\xf2\xc6\xdf\xe6\x10\x06\xd3\x2f\x1e\xe2\x81\x8b\x2d\xb1\x28\xf4\x3e\xec\x9c\x4d\x0e\xcc\x57\x78\xa5\x2a\x9f\x37\xee\x29\x98\x5c\x81\x6a\x8f\x92\x33\x6c\x7f\x52\xaf\xe9\xa4\xda\xf6\x74\xb1\x35\xf1\x62\xab\x88\x69\x0b\x8c\xf6\x88\x99\xcb\xd5\x98\x54\x4b\xfa\x81\xef\x26\x52\x8f\xd8\x85\xca\xb0\x36\x7f\x85\xcf\xfc\x47\x7c\xc5\xbf\xc4\x37\xac\xb4\x2b\xc8\xef\xe8\xe2\xaa\xa3\x2c\xb5\xe9\xa3\x5d\x98\xe2\x07\xee\x63\x6f\x9b\xfd\x5d\xd1\x54\xe7\x28\x34\x12\x85\x47\x00\x3b\xa0\x24\x3a\xfd\x6a\xe7\x51\x2e\x01\x7a\x73\x25\x17\x83\xa4\x69\xfa\x1c\x5b\xb6\xc9\x38\xa7\x47\x10\x0b\x5a\x78\x9d\x34\x93\xd7\x31\xb8\x23\x2c\x30\x2c\xba\x50\x16\xe8\xe1\x6a\x3b\xc1\x88\x83\xfe\xab\xe0\x27\xfb\xca\xe1\x0d\x47\xa0\x2f\x16\x98\x39\x60\x7c\x02\x69\x46\x92\x98\xc7\xf3\x12\x68\xd2\xb3\x6f\xd8\xb9\xfa\x94\x18\x51\x2d\x7c\x13\x6f\x60\x24\x08\xf3\x3d\x81\x24\x70\x1f\x81\xe8\x00\x29\xe6\x45\xed\xea\x9b\x7e\xd5\xef\xf7\x41\xd7\x4e\xaa\x38\x2b\x1c\x43\xb4\xe1\x19\x8e\x72\xdb\x2a\x73\xc4\x46\xb0\xb6\x2a\x64\xaa\x23\x26\x6a\x20\x6a\x38\xe6\x80\x94\x94\xed\xc2\x1e\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\xec\x65\x86\xeb\x33\x5f\x90\xba\xdb\x8a\x67\xc7\xb9\xf6\x99\x1b\x3e\xd3\xea\x34\xa2\x84\xc0\x10\x31\x45\xba\x29\x5a\x39\xae\x8c\xc1\x0d\xd4\x4e\x97\x14\x71\x02\x44\xaf\x84\xe7\xde\x80\xf5\xd8\x7e\xf5\x81\x60\xab\x14\x30\x8c\xfb\x0b\x1e\xe9\x48\x38\x8d\x15\x8a\x7b\x63\x06\xd1\x8a\x89\x00\x83\x02\x25\xfb\x4c\x7c\x44\x11\x55\x34\x56\x64\xb7\x57\xeb\x85\x44\x8d\xc3\x19\xad\x77\x46\xc6\xa5\xc1\x4e\x7c\x8b\x44\x65\x7a\xd3\xd4\xab\x13\x4f\xd0\x15\xe4\x9f\x44\x54\xe3\x00\x60\x98\xc6\xa8\x66\x0b\x8d\xf7\xb7\x93\xc2\x61\x91\x24\xf0\x82\x25\x4b\xf6\x5e\x24\x15\x79\xdf\x85\xa0\xdc\x8a\x37\x39\xba\x9e\x1b\x7e\xd6\x41\x92\x0e\x9f\x91\x32\xe3\x6d\xa8\xcb\xb1\xf1\xce\xd3\x98\x16\x03\x6e\x74\xa7\x96\x3b\x41\xbd\x18\x96\x39\xeb\x4b\x69\xa4\x92\xae\xa0\xa7\xa4\xfa\xc2\xf4\xc7\x12\xcf\x3d\xfa\xf0\x43\x96\x47\x51\x3e\x79\x7a\xea\xa9\x1f\xbd\x64\x4f\x93\x13\x22\xcb\xfe\xe4\xb7\x8f\x21\xb4\x97\xaa\xd4\xc5\x27\x53\xf9\x71\x2a\x41\x8d\xff\xb0\xd4\x50\x41\xe9\x06\xf2\x3d\xb5\x88\x54\x98\x8b\xe1\xa9\x0e\xe9\xa0\xd2\x0d\xfa\x95\x42\xe2\xc5\x54\x6e\xf1\x1c\x55\xfe\x35\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\xbd\x5a\x0c\x46\xa2\x00\x02\x5c\xc5\x24\xe5\x2f\x79\xb7\xe7\xcc\x68\x30\xd0\xcb\xed\x9c\x43\x4a\x3a\x4a\x86\xec\xb0\x29\x9c\xe3\x75\x08\x49\xc4\x09\x61\xde\x88\xe1\xbe\xae\xd4\x93\xa1\x75\xaa\xe7\x7c\x6c\x7a\xc4\x96\x8a\x98\xaf\x29\x69\xec\xe2\xee\xd4\xfc\xc5\x25\xed\x42\x99\x0b\xde\xbc\x6a\xde\xa3\x50\x89\x0c\x91\x46\x5c\xd3\x86\xd3\x88\x9f\x1f\x7d\x46\x67\xce\x3b\x0c\xc0\xbd\x91\xd0\x4a\xb3\x44\x12\x55\x1b\x26\xe8\x0c\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\x71\x85\x72\xcc\x56\x5e\x67\xad\x0b\x9e\x0a\xc9\x72\x34\xdb\x16\x93\x2e\xdc\xcc\x49\x19\xff\xe4\x6f\xd5\x14\xc9\xfc\xd7\x8a\x27\xca\xdb\xcf\x74\x03\xfa\x7e\x97\xab\x4a\xf4\x00\x4c\x77\x67\xdb\xb5\xf1\x57\x9e\x5b\xbe\xdf\x60\x7c\x55\xe9\x1c\xcb\x51\xf4\x09\xc5\xdb\x89\x8c\xf8\xfa\x11\x00\x7b\x96\xa1\x48\x6a\xd9\xfb\x7b\x55\xd6\x53\x35\xe7\x5a\xdf\xa0\xd9\x28\x0c\x5c\x86\x69\x52\x9f\xa3\xe0\x0e\xbe\xf5\x31\x71\x2b\x8d\x5b\x1b\x2e\xf2\x0d\x09\x4b\x64\x79\x20\x35\x22\x8d\xa9\xd4\x3d\xfc\x84\xbb\x20\x6a\xe9\x56\x09\x18\x3e\xec\x2e\x23\x13\x12\xb8\x5f\xe0\xee\xb4\x4c\x88\xf7\xb2\xf9\x02\x03\xfb\x7b\xb7\xd7\xe2\x3a\x8b\xab\x08\xb1\xca\xbb\xa6\x17\xce\xed\x4a\xb2\x33\x0e\x82\x5c\x23\x49\xd6\xe0\xdc\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\x6c\xcb\xc4\x7b\xc2\x2f\xcb\xb0\xbc\x94\x67\xdb\x0c\x74\x16\xd0\x13\x8d\x70\x36\x63\xd4\xf0\xd5\x16\xda\x92\x90\xc7\xeb\xbd\x42\x6f\x14\xd7\x5c\x30\xc5\x25\x7a\xdd\xcb\x29\x77\x7a\xde\x6b\xe2\x26\x0b\x20\x35\xcc\xfa\xe4\xc1\xb9\x1b\x69\x66\x21\x8b\xb7\x05\xac\x0c\x57\x6e\xb4\x96\xa4\x1d\x06\x9f\xa0\xd9\xf4\xe1\xa7\x5f\x47\xb0\xa2\x34\xf7\xde\xbb\x4e\x6a\x4a\x97\x55\xe9\x49\xf7\x3a\x65\x27\x6d\xe2\x17\x75\xcf\xe9\x03\xae\x19\x01\xcc\xcc\xa9\x92\xde\x66\x0f\x3f\x5f\x49\xa4\x4e\x4f\x57\x0d\x13\x69\x05\x74\xad\xc6\x36\x0a\xcb\xa8\xbd\x62\x66\x32\xa0\x00\xc5\x24\xbd\xd2\x41\x19\xab\x30\xd8\x5e\xe5\x21\xe9\xf6\xf3\x9c\x49\x37\xfa\xc9\xb3\x41\xa5\x80\x0f\xdb\x4a\x90\x46\x60\xb3\x09\xb9\x36\x4f\x15\xbd\x26\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\x05\xa7\x7f\x5a\xec\x95\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\x6c\x2e\xa0\x09\x13\xa2\x4f\x30\xc2\x59\x89\x45\xa3\xd9\x80\x99\x22\xe0\xd0\xd9\xd4\x54\xba\xaf\x93\xed\x48\xd1\xe8\x35\x60\xa9\xfc\x54\x3c\x6c\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\x62\xdf\x2e\x8f\x94\x1f\xeb\x7e\xe9\x88\x97\xb2\xe0\x57\x24\x9a\xad\xca\xd0\x51\xa4\x5f\x1e\x89\x94\x5f\xcf\x2a\x9e\x37\xb8\x0b\x51\x0c\xa0\x29\xac\xac\x3a\x22\xbb\x14\x6c\xa3\x98\x00\x58\xbe\xef\x17\x09\xbe\x6b\x33\x90\xf5\x32\x0b\x09\xd7\x56\x06\xde\xa1\xa8\x25\xaa\xc9\x92\xf1\xe9\x79\x62\xe6\x7b\xbf\x1f\x68\x5a\xa5\x15\x00\x7c\x0c\xb4\x73\x33\xca\x3f\xf7\x63\x84\x32\xf9\xab\x3d\x4f\xf4\xef\xc4\xe2\xef\xc4\xe2\xff\x86\xc4\xe2\x71\xe3\xd7\x3f\xed\x7a\xfe\x99\x08\xd8\xd2\x78\xe1\x1d\xde\x7c\x18\x98\x7a\xbd\xf1\x6a\xe1\x30\x26\x6f\xff\x7b\x89\xc5\x0f\x7c\xda\xbf\xc4\xf7\xdf\x4c\x2c\x44\xad\x30\x45\xad\x30\x20\x95\xff\x99\x08\x18\x0f\x1a\x35\x6d\x53\xd4\xb8\x62\xd2\x0a\x63\x36\x6d\x81\x37\xff\xbd\xc4\xe2\x27\x3e\xfb\x5f\xe2\xfb\x3f\x93\x58\x94\xd0\x48\x11\xd2\x9a\x58\x64\xdf\x13\x8b\xec\xac\x29\xe1\x74\x36\x05\xf5\x0e\x8c\x3a\x2d\xa9\xd2\xa4\x16\xb6\x44\x74\x16\xe8\xf8\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\xc4\x55\xe3\x70\x4b\x6c\x20\xc7\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\xb4\x1d\xdf\xa9\x82\x7d\x3b\x44\xcd\x30\x91\xb3\x5a\x0b\xb7\x13\xad\x9e\xf5\x33\x73\xbe\x73\xcb\x0b\x1b\x9e\x1e\xbe\x07\x06\x0e\x7b\x35\xc0\x42\x70\x17\x95\x89\x1b\x20\x86\xf1\x0e\x7f\x08\xea\x19\xc9\x7d\x0c\x7a\x30\x0b\xaa\xee\x15\x1d\x1f\x27\x7e\x44\x41\x71\x86\x91\x97\xbf\x30\xc8\xe9\x42\xdc\x9f\xd5\xf3\xc6\x5e\xaa\x3b\x7f\x0f\x08\x2f\x44\xb5\xe9\xf2\x66\xd1\x72\x08\xf5\x6b\x93\xc0\xb3\xcc\x23\x32\xa4\xc7\xfa\xa8\x5d\xba\x53\x3c\x11\x14\x6f\xdd\x5f\xe8\x4b\x2e\xf2\x07\x83\x01\x5e\x9a\x0c\xd2\x7c\x9a\x78\x16\x46\x6d\xab\x4a\x46\xee\xc5\xc1\x34\x33\xf5\x61\xa0\x98\xc5\xdd\xc5\x17\xf5\xf5\x70\xc5\x32\x23\x00\x66\x9e\xe9\x6e\xf2\xeb\x8b\x5e\x2b\xa0\x01\xef\x53\x51\xac\x64\x33\x18\xc9\xc5\x66\xce\xc1\x35\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\x0e\xe7\x93\x67\xc6\xcb\xe0\xe6\x71\xa6\x4d\xe8\x14\x5e\x2d\x4d\x50\xed\xa7\x43\x72\x53\xf4\x48\xc1\xda\xf2\x99\x77\xc7\x4c\xb1\x12\xbe\x24\x28\xcf\x12\xd6\xce\x28\xcf\xd3\xc4\xfe\x4d\x8f\x6c\xcc\x17\x21\x65\xcc\x8c\x25\x04\x15\x75\xe5\xee\x8d\x7e\x83\x14\x3b\x85\x98\x13\x4c\x4a\xf9\xc8\xd3\xe6\xd5\xa1\x8d\xcb\x12\x09\xb2\x19\x9c\x6e\x4f\xa5\x09\xa8\x60\xf0\x71\x05\x12\xef\x2d\x18\x21\x70\x87\xea\x36\xee\xc2\xa5\xdb\x3a\xa4\x42\x37\xef\x11\x64\x5b\xa8\xf6\xee\x9d\xef\xf2\xc8\xeb\x26\xbe\x46\xf7\xb4\xf8\x4f\x78\x59\xca\x34\xe9\xfa\xa6\x74\x84\xa1\xcb\x39\x25\x34\x4d\x59\xb8\xd2\x2e\x3b\x4d\xb0\x08\xc8\xa5\xda\x79\x42\xe6\xea\xaf\xcb\xd2\xba\xa7\xf3\xc8\x4c\xc4\x7b\x92\x07\xd8\x24\xaa\x51\x58\x90\x72\xa4\x00\x8c\x53\x58\x40\x45\xed\x16\x36\x47\x07\x4c\x11\x1b\x23\xbd\x73\x2d\x10\xf1\xf0\x6e\x99\x4b\xe3\x81\x74\x18\x26\x0f\x80\x13\x64\x53\x95\x25\x04\xbc\x5f\x1d\x91\x45\x60\x97\x86\x2b\xec\x44\x45\x86\x31\x64\x7e\x0e\x0e\x3c\x40\xb8\x71\x1a\x2d\x35\x4e\x9b\x34\x65\xe8\xcc\x9b\x69\x97\xe8\x09\x78\xc3\x73\x7e\x4d\x49\xb8\x18\xe0\xb5\x6c\x5f\x78\x59\x4e\x4a\x96\x50\x21\x87\x46\x82\xfa\xa6\xbc\xf8\xa1\x9c\x9e\xca\xb0\xb7\x14\x91\xf1\x4f\xb4\x9f\x3b\x3d\x54\x68\x97\x27\x1d\x98\x57\x37\x64\x93\x47\x9a\x8f\xe0\x22\x66\x82\x68\xc9\x50\x30\xee\x17\x2f\x1c\xee\x32\xc0\x30\x29\xad\x8f\x34\x47\xb7\x98\xf8\x14\xff\xdc\x5b\xe0\xcb\x26\xfd\xa3\x9b\x13\xfe\xc7\xaf\xa2\x8a\x76\x48\xf7\x53\x55\xfe\xaf\xff\x40\xd8\x76\x48\x77\x53\x55\xd6\xed\x2f\xdf\xb2\xae\x7b\xfe\xbf\x00\x30\x8e\xe3\x71\x44\x8e\xcd\x3b\x05\x60\x10\x04\x57\xe0\x6f\xbb\x21\x4f\x46\xa6\x99\x7e\xf9\x06\xee\xc0\x1d\x86\x21\x3b\x18\xc1\x8e\xc8\xb7\xff\x40\xf8\xff\x40\xd8\x38\xb9\xb7\x9f\x2b\xe0\xe7\xe5\x33\xe8\xb2\xdd\x3d\x2f\xcb\x5f\xbe\xfd\x07\x8c\xdc\xb7\x7f\xdf\x76\xf1\x2f\xdf\x54\x18\xa1\x76\x38\x92\x41\xc4\x91\x1c\x20\x10\x3b\xc1\x08\xe5\xe0\xc8\x52\x21\xd8\x11\xdf\x81\x19\x82\x1f\x91\x88\x38\x52\x3b\x70\x07\xa1\x47\xec\x48\xed\x20\xea\x88\xef\xe0\x23\xde\x52\x47\x78\x87\x1e\xa1\x1d\x04\x1f\xa1\x1d\x71\x84\x02\x18\x3d\xa2\xd8\xee\xd3\xae\x94\x41\x3b\xfc\x08\xef\x20\x70\x85\x03\x8f\x04\xf6\xd5\x7e\x86\xa0\x23\xf9\x99\x89\x62\x47\x9c\xfa\x6a\xb7\xa1\xc3\xd7\x10\xb5\x83\xf1\x23\x46\x7e\xb5\x9f\xa1\x2f\x84\xe4\x0e\x01\x8f\x18\xf5\xd5\x7e\xcd\xfa\x90\x81\x44\x07\xec\xb8\xa1\x3f\x40\xd0\x11\xdb\xc1\x47\xe2\x00\x51\x47\x64\xbd\xc8\xd6\x2b\xc8\x81\x70\x32\x3b\x40\xc4\x11\xfb\x6c\x74\xc5\x89\x41\x01\x42\x1e\x11\x62\xf7\x69\xc1\x0f\x4e\xe8\xb8\x12\x83\xec\x20\xfc\x7b\xf3\x19\xc0\x8f\xe4\x01\x39\x12\x3b\x08\x39\x22\xe8\x57\xfb\x19\x41\x8e\xd8\x01\x3b\x92\x3b\x98\x5a\x77\xfa\x69\xbf\x90\x1d\x88\x95\x6f\xd8\x11\x27\xbf\xda\xad\xff\xb0\xf6\x13\x3b\x08\x5e\x5f\x9f\x1e\xe4\x88\x1f\xb0\x23\xb6\x83\x88\x23\xf4\xbd\xfd\x8c\xe0\x47\xea\x80\x1c\xd1\x1d\x0a\xad\x1c\xf9\xb4\x5f\x58\xc0\x23\x75\x80\x8e\x70\x76\x80\xc8\x23\xe6\x40\x10\x9a\xad\x17\x4b\x05\x41\xd4\x91\x3a\x60\xd0\x00\x61\x47\x24\x3b\xa0\xd4\x11\x76\x20\x90\xcc\x50\xfc\x88\xac\x7d\x68\x76\x58\x2f\x7f\xf0\x84\x74\x70\x24\xc3\x89\xa5\x82\x57\xb6\x10\xf0\x91\x8a\x8e\xe4\x0e\x3f\x52\x3b\x64\xe5\x01\x74\xa4\x76\xc4\x11\xdd\x41\x58\x0b\x81\x2b\x25\x2b\xed\xe4\x11\x5f\x2f\x02\x04\x3e\xe2\xd0\xee\xd3\x7e\x6d\x1a\xfc\xe2\x20\x0c\x1e\x31\xf8\xab\xfd\xce\x43\xfc\x80\xac\xbb\xfc\xb9\xf3\x2f\xee\xc1\xab\x8a\x81\xe4\x57\x0b\xfe\x90\x3c\xba\x8a\x00\xfa\xde\x7e\xf6\x7d\x24\x0e\xe8\xaa\x93\xf0\x91\x24\xbe\xda\xcf\x00\x7c\xc4\x0f\xe8\x8a\x1e\x5f\x35\xe4\xd3\x7e\x46\xb0\x23\xb4\xb2\x78\x87\x60\xeb\xeb\xd3\x47\x1e\xe1\x03\x7c\x44\xcb\x03\x84\x1c\xd1\x03\x7c\xc4\x02\x92\x3a\x12\xf8\xee\xd3\x7e\xe9\x17\xba\x4d\x24\x76\x08\x72\xc4\xa0\xaf\xf6\x6b\x08\x3c\xa2\x1f\xb1\xc3\x47\xf8\x7b\xfb\x9d\x6c\xe4\x40\xae\xfa\xba\x5a\xca\xd6\x7c\xfa\xe1\xe3\xa6\xb1\xc4\x0e\xc6\xd7\xd7\x97\x4d\x40\x47\xe4\x00\xc3\x47\x74\xb7\x9a\x1d\xf6\xd5\x7e\x8d\xc1\x9b\x5a\xe0\x3b\x1c\x3b\x92\xd4\x57\xfb\x35\x84\xad\xca\x7e\x24\x23\xe2\xb8\x72\x72\xd5\xc7\xd5\x82\xc8\x23\xbc\x5b\xb7\x82\xa0\x47\x14\xdf\x7d\xda\x1f\xeb\x50\x3b\x7c\x35\x0e\xf2\x08\x43\x5f\xed\x77\x8b\xa5\x76\xab\xb5\xa0\x9b\x69\xc2\xdf\xe9\xdd\x21\xab\x58\xa0\xf2\x00\xe1\xeb\x36\x8f\x78\x74\x80\xb6\x3d\xaf\x0a\x49\xac\x0c\x80\x0f\xc4\xba\x25\xe4\x08\xb5\x07\x72\x13\x0b\xb2\x02\x43\xeb\x45\x80\x22\x47\x6a\xb7\x35\x3f\xd4\x15\xdb\x41\xab\x99\x52\x47\x94\xf8\x6a\xbf\xeb\x38\xb9\x43\x8e\x1b\x8d\x38\xf2\xd5\x7e\xb7\x0b\x62\x87\x1e\xf1\xd5\x0f\xad\xda\x81\xfe\xd0\x8e\xc3\x8a\x09\x3b\xa2\x11\xf8\x19\x3f\xc2\xbb\x15\x07\xb1\xaa\x1f\xd2\xae\x3b\xda\x8c\x14\xde\x61\x47\xa4\x5c\xbd\xd8\x0e\x3e\x92\xd1\x6a\xdd\x3b\xf8\x43\xc3\x3a\x84\x6f\x9e\x6b\x9d\x83\xb5\xc4\x77\xe7\xb4\x5e\xc0\xd0\x11\x0d\x10\x68\xf3\x0e\xd0\x77\xef\xb0\x4a\x10\x5d\x61\x90\xd5\x9a\x61\xe2\xab\xfd\x6e\xe9\xe8\x8e\x5a\xf7\xb1\x79\x2e\xe4\x57\xfe\x0b\x5a\x67\xe1\x47\x7c\x87\x6d\xaf\xaf\x4e\x62\x73\x4f\x68\xb4\xa9\xdf\xaa\xbc\xab\x0e\x92\x07\x04\x3a\xe2\x07\xf2\x88\xb5\xab\x27\xa3\x56\x05\x44\x0f\x9b\x1a\xac\xb6\x99\x41\xe4\xf2\x0d\xf8\x3d\xef\x8e\xe2\x54\x12\xc0\x1f\xef\x8e\x80\x9b\xe7\x42\x4b\x12\xdd\xa1\xe4\x11\xdb\x91\xe8\x61\xfd\xdf\xc1\x89\xf2\xf0\x75\x7d\xf8\x1a\x1b\x28\xe2\x0f\x30\xe2\x41\x14\xc4\xd0\x07\x23\x04\x62\xab\x0d\x80\x47\xa8\x3c\xac\xd6\x8e\x1d\xe1\x00\x22\x8f\x10\xb5\xfb\xb4\x1f\x75\x59\x6d\x19\x29\x71\x70\xf5\x1b\x1b\x04\x7a\xc4\xb0\xdd\xa7\xfd\xd2\xc1\x75\xd3\xe0\x06\x72\xf8\x23\x24\x07\xe4\x88\x28\x10\x8c\x6c\xcb\xfd\x16\xc7\x87\x71\xe0\x52\x7d\x36\x00\x7f\x27\x08\x5f\x41\x09\x64\xf7\x69\x3f\xa0\xab\x8f\x82\xb0\x72\x15\x29\x18\x40\xd8\x11\x23\x76\x9f\xf6\xb3\x14\xbc\x0a\xfc\x88\xff\x9a\x9c\x7f\x46\xb1\x23\x8f\xf8\x01\xc2\x1c\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\x0e\x01\xaf\xb2\xf8\x9a\x51\x6d\x26\x8c\x94\xbf\x52\x9d\x7f\xd6\xb0\xe1\x40\xfd\x54\xb1\x7f\x93\x18\x6a\x07\x21\xeb\x11\x76\x84\x69\x08\x3b\xe2\x2b\x4f\xd6\xf6\xc3\x00\x8a\xdc\x41\xeb\x19\x3c\xac\xe3\xc1\x6f\xc7\x21\x6c\x75\x44\xd8\x91\xc8\xfe\x78\x7c\x6b\x86\xdf\x1d\x3f\xfc\x18\x5f\x2a\x70\x87\xa3\x47\x2c\xfb\xb1\x10\xb6\xfb\xb4\x5f\xde\x66\x75\x2d\x64\xb9\xb1\x62\xf5\xb1\xeb\xc5\x7a\x82\xfc\x01\xe8\x81\x5c\x2a\x72\x3d\xd9\x56\x46\x64\x87\x55\x3b\xff\x69\x6d\xf0\xf0\x1b\xda\x20\x64\xf7\x69\x3f\x4a\x06\xef\x88\x23\x5e\x7e\x2d\x84\x38\x10\x4a\xae\xda\xb6\xbd\xa5\x56\xf0\xf5\x40\x3e\x7e\x3f\x13\x37\xe0\xdf\xdd\x24\xf8\x93\x09\xd9\x11\x77\x70\xe2\x08\x2b\x10\xb9\x1e\x4a\x18\xb5\x54\x07\x9c\x3a\x92\x07\x14\x5c\xe5\x0c\x82\x6b\xd8\xb5\xe1\x26\x36\x52\x88\xef\xa4\x7c\x76\x7f\x84\xb2\xdf\x65\xce\xee\xb3\xe3\xf2\xf0\x9d\xd6\x45\x45\x57\x9f\x8c\x91\x47\xea\xd3\xb9\x23\xd7\xc0\x03\x3f\x22\xd9\xef\x71\xe2\xa7\x14\xbf\xc4\x8c\x6f\xa7\x00\xfe\xf3\x14\x58\xcf\x19\x62\x59\x1d\x1b\xb5\x83\x50\x72\x65\xe8\x8a\x0e\xfe\x2e\x0f\xe4\x9f\xf9\xb1\x5b\x67\xe0\xc3\xef\x6a\x15\xb8\xfb\x8e\xe7\x0f\x34\x14\x24\x91\x10\x43\xbf\x6d\x1d\x87\xe6\x19\x44\x79\x37\xff\xf2\x0d\x3c\x42\xd8\x3f\x98\xd0\x7a\xba\xac\x0a\xbf\x3a\xc5\xef\xfa\xbf\xbe\xfb\x2f\x62\x05\xbf\x63\xa5\xc8\x2d\xda\x41\x8e\xe4\x77\x33\xda\xfd\x16\xe7\x9a\x0b\xac\x57\x20\xfd\x3f\xfe\x3b\x59\x4a\x95\xc7\xff\x90\xa4\xfc\x57\xa7\x17\x7f\xf4\x9c\x90\xdf\xc9\x71\xfe\xbf\x28\x0b\xde\x6d\xd2\xfd\xd2\x77\x77\xf2\x7b\xc2\x93\xc7\xbf\x7c\x53\x82\x39\x79\xff\x27\xfc\xed\xbf\x9c\xfd\x10\x6b\x3e\x00\x7e\xa5\x3e\x6d\x37\x97\xc9\x17\x77\xca\xbc\x4e\x82\xb7\xf8\x0e\xe2\x3c\xa9\xbb\x6d\x11\xcb\x11\x25\xee\x3f\xa1\xff\xfc\xb6\x4b\xbf\xba\xed\x3a\xef\xda\x5f\xbe\xf5\x6d\xf2\xb6\x9e\x41\x94\x5c\x6a\xbb\x4d\xbe\xed\x26\xe8\x97\x6f\x6b\x5a\xf0\x6d\x37\x43\xbf\x7c\x83\x40\xe8\xdb\x6e\x82\x7f\x74\xad\x57\x47\x70\x95\xd5\x77\x34\xd7\x77\x50\xb7\xf7\xe6\x5d\xfd\xf2\xad\x0a\xba\x77\x3e\xfd\x3f\x9f\xb0\xe9\x00\x6d\x31\x30\xfc\x3f\x7f\xd0\xd7\x3c\x77\xcd\xfd\xbe\x72\xe0\x1b\xf8\x6d\xb7\xbe\x3f\x44\x4d\xd9\xbc\x37\xb5\x48\xe0\x28\x4e\xd0\xef\xe2\xfd\x07\xe0\x23\x44\xfc\x16\x1c\x8c\x82\x04\xfe\x7d\x70\x04\x42\x7e\x03\x1f\x87\x11\x18\xc7\xbf\x0f\x8f\xa2\xbf\xc5\x1f\xc3\x21\x14\xff\x01\x39\x18\x81\xfd\x06\x3e\x22\xa8\x38\x22\x7e\x1f\x1e\xa7\xc8\xdf\xc0\x87\x01\x89\x86\xd4\xef\xc3\x93\x10\xf5\x1b\xf8\x20\xc4\xc9\xe0\x0f\xe0\x29\x04\xfd\x0d\x3c\x15\xa1\x18\x45\xfe\x2e\x3c\xf4\x5b\x60\x04\x0e\xc8\xe4\x87\x69\xfd\xa3\xf6\xfc\xca\x86\x57\xf3\x44\xb7\x1c\xa5\x5c\x83\x3e\xfc\x48\x38\x14\x75\x5a\x93\xaa\x0c\xc5\x96\x6f\x5f\x36\xbe\xaa\xff\x7f\xc0\xc8\x77\x85\xfb\x9f\xff\xe0\x06\xfe\x1d\x14\xbf\xf2\x0a\x2b\xa9\xef\xa6\x48\x36\x32\x49\x12\x46\x48\xe4\x7b\xd7\x61\xcc\xe3\x2e\xfb\xe5\x1b\xfc\x1b\xfc\xc4\x11\xdb\x51\xd0\x11\x72\x88\x35\x29\xc4\x8f\x50\xb9\xa6\x3c\xd0\x9a\x70\xad\xe9\xe5\x7a\xb1\xf6\x3a\x14\x94\x1d\x90\x23\xe9\x10\xd8\x9a\xfd\x6c\x6e\x13\x5f\x7b\xa8\xf2\x80\xae\x6e\x18\x77\x28\xe8\x44\xac\x89\x24\xbc\xce\x05\x3f\xf8\x50\x87\x04\xcb\x35\x67\x22\x8f\x64\x86\x1d\x51\x05\x5d\x63\x69\x82\x2a\x3f\x51\x73\xb6\x26\x71\xe5\x9a\xc3\x1e\xa8\x23\xb2\x65\xac\xc8\x11\x19\xf0\xec\x80\x2e\xd5\x1a\x27\xef\x40\x05\xa5\x76\x04\x74\x44\x32\xf4\x88\x2a\xd8\x16\x36\xe0\x25\xfa\x09\x72\x89\x0c\x5d\x43\x0b\xe2\x93\x08\x92\xd9\x9a\x41\xfc\xe0\xec\xa7\x7a\xf1\xed\x5f\x19\x39\xfc\xef\x19\xf9\x9a\x23\x7d\x8c\x1c\x03\x8f\x20\x8c\x7c\xec\xfc\xab\x17\xfe\xd9\xfb\xdf\x32\xf4\x8f\xaf\xf8\x67\x7d\xc3\x11\x94\x82\xfe\x4d\xe5\x24\x40\x08\xc1\xc3\xff\xad\x72\xfe\x21\x27\x90\x7f\x93\x13\xd0\x11\x83\xa0\x2f\x5e\x40\x47\x02\xc2\x3f\xbc\xc0\xb1\x23\xbc\xf5\xc3\x3f\xfb\xff\xfa\xdc\xf8\x61\x07\xf8\x7a\x3c\x63\xd8\x11\x5b\xf3\x55\xe2\x70\x84\x57\x6d\x3c\x1c\x91\xad\x0a\x70\x44\x0e\xc4\x11\x39\x7c\xd2\x56\x64\x8d\xcf\x0f\xd0\x96\xab\x1f\x09\x0b\xa6\xd6\x54\x7b\x35\x1a\x78\x1d\xc3\xd1\x68\x9d\xb9\x65\xb9\xc8\xe1\x93\x96\xad\x19\xe0\x61\x8b\xca\x91\xc3\x56\x10\xc2\x0e\xd0\x61\x0d\x5f\xb6\x44\x9d\x38\x6c\xf8\xd6\x55\x57\xb8\x35\x55\x39\x92\x87\x23\xb5\x83\xbf\x4a\x22\x2b\x21\xd0\x71\x2b\xa6\x1c\xa1\x2d\x55\x27\x8e\xf8\x6e\xcd\xdc\x89\x23\xf4\x29\x2e\xe1\x87\x23\xba\x83\xd7\xfc\x16\xdb\xe1\x6b\x3e\xfd\xa9\xb6\xad\xd9\xe1\x66\x1b\xeb\x05\xbe\x21\x3a\xc2\x6b\xe6\x7e\xf8\x54\xc7\x90\x1d\x58\x1d\xa8\x35\xae\xc1\x8e\x48\x74\xc4\xb6\xee\x6d\xbf\x3b\x68\x03\xda\xd8\x40\x7c\xb6\xbf\xa2\x85\x8e\xf0\x01\xdf\xba\xd7\x44\x73\xb5\x42\x62\x07\xaf\xef\x77\xe8\xee\x88\xae\x49\xf0\x3a\x15\xde\xa1\x1b\x05\xc4\xb6\x25\xec\x53\x91\x80\x8f\x44\x05\x6f\xb5\xb7\x0c\x3a\x42\xd1\x4a\xca\xca\x25\xe8\x83\x6d\x2b\x4a\x61\x2b\x43\xb6\x9a\xde\xa7\x98\x76\xa4\x96\x0a\xd9\xe8\xc8\xa0\x23\xe6\x20\xe4\x1a\x68\x23\x11\xb8\x5b\x59\x87\x7e\xed\x62\x0d\xc3\xd1\x1d\xb8\x51\xbf\xce\x05\x3f\x5c\xda\x84\xf7\x6b\xfc\xdb\xdc\x61\x03\xdf\xea\x7d\x6b\x5c\x49\x45\xbf\x01\xdb\xaa\x15\x1b\xc3\xb7\xfa\xc0\x87\x93\x2b\x21\x87\x75\x87\xd1\x91\x38\xae\xf9\xd5\x46\xdd\xca\xae\x35\x5a\x24\xa2\x0f\xed\x1f\x29\xe1\x9b\x10\x3e\x53\x36\x0f\x7a\x84\x56\x8a\xf1\xc3\x86\x08\xfd\x90\x7c\xc4\x8e\x9f\x29\x1f\x76\xc3\xdb\x0b\x5f\x35\xe5\x83\x86\x5a\xf7\xb2\xea\xcc\x3a\x4a\x1d\xd1\x15\xd7\x4a\x33\xb9\x11\x0c\x6d\x5b\x5c\xe9\x43\x76\xe0\x61\xf5\xb6\xab\x6a\xae\x64\x6d\xf4\x1e\x56\x22\xd7\xdd\x7e\x57\x84\x23\xb4\x54\x30\xb9\x2a\x1f\x1a\xad\xdb\x45\x3e\x62\xde\x58\x45\x1d\x57\x79\xe2\x9f\x1d\xfd\x21\x29\xc8\x47\x58\x2b\xe2\x6d\x5b\x9f\xc2\xc8\x87\xe5\x5f\x62\xf8\x0e\x42\xae\xd3\xb6\xce\x95\x1d\xd9\xe1\x48\x7d\xd6\xfc\x90\x8d\x1c\x36\x05\x86\xb6\xb2\x21\xb5\xd5\xa2\xb6\x0a\xd7\x56\x31\x5b\x07\xb7\xc3\x60\xc5\xb3\x9e\x3f\x6b\x60\x4e\xac\x18\xb1\x1d\xf4\xd1\x7c\x74\x2b\x18\xe0\x5b\x19\x87\x3c\x22\x2a\xf2\x55\xe5\xc4\xa3\x23\x76\xdc\x6a\x34\x9b\x36\x6e\x2c\xfe\x62\xd4\x87\xbc\x95\xd9\x9b\x34\xa8\x95\x38\xf8\x23\xac\x95\x49\xab\x64\x8f\x9f\x3c\x88\x8a\x8e\xd4\x06\x0c\x7f\xe6\x6c\x9b\xf8\xc9\xcf\xcd\x2b\x6c\xc4\x62\x5f\xfc\x85\x3e\x76\xb9\x54\x07\xec\x88\xac\x34\x6c\x47\xdf\xea\x1f\x56\x73\x5c\x8d\x73\x55\xc9\x8f\x98\xb1\x1f\xc8\x0e\x9b\x5c\xe0\x1f\xd8\x36\xb9\x1d\xa9\xad\xf7\xc3\xe0\xf5\x50\x86\x4f\x10\x11\x6d\x03\x1f\x39\xfc\x84\x47\xb7\x75\xe1\x0f\x1a\x64\x95\xde\x86\x79\xf7\xdd\x47\x6c\x56\x83\xee\xa0\x68\xcd\xcd\x57\x01\x6d\x75\x3a\xe8\x88\x7e\xa5\x64\xbb\x15\x76\x25\x1e\x3e\x6e\x15\x35\xf8\x80\xae\xd4\x61\xeb\x69\x7e\x84\xb6\x9a\xdc\xca\x1a\xf8\x63\xeb\x1f\x6f\xb7\xb2\x76\xb3\x93\xd5\x5b\x20\x4b\xb5\x4e\x20\x7f\x18\x32\xf6\x91\x36\xbc\x95\x53\xa1\xd5\xd2\xb0\xe8\xb3\xfb\x9f\xbc\xd8\x98\xb4\xb9\x88\x68\x2b\x3e\x6e\x94\xa3\x1f\x63\xdb\x56\xdc\xb0\xac\xa2\x3d\x6c\x88\x3e\xda\x84\xae\x2c\x5d\xed\x60\x65\xfe\xe7\x3f\x6c\x53\xa3\x2f\x75\xf8\x58\xde\xba\x0c\xb6\x2d\x83\x6e\x21\x04\xf9\x41\xb7\x52\xb0\xca\x98\xda\x6d\x6e\xf2\xb8\x55\x51\xb7\xf9\xf0\x0e\xfd\xae\xb4\x5b\x5d\x78\x33\x1b\xf2\x53\x38\xf9\xe4\xe2\xab\x57\x43\x0e\x9b\xdb\xc6\x3e\x46\x48\x1d\xc9\xed\xf3\x0c\x6c\x73\xfc\xf8\x4a\xe2\xaf\xe8\x3c\xfc\xd8\x2f\xf1\xa5\xe2\xab\xdf\xfc\xec\x09\x3d\x52\xd5\x96\xdc\x22\x9b\x27\x83\xa2\x75\xdd\x8f\xd7\x81\xbe\x9b\xc9\x4f\xe7\xb4\xee\x09\x1d\x56\x47\xb7\xee\xe6\x83\x6e\x75\x29\xe0\xb0\xf1\xf5\xb0\x2d\xfd\x61\xf6\xba\x6b\x78\xa9\x88\xcd\x17\xa0\x19\xf4\xa9\x79\x60\x1f\x37\x79\x84\x3e\xca\xb8\x29\x24\xb6\x79\xbd\x03\xb4\xe2\xfd\x15\x09\xe8\x77\xb5\xde\xfe\xfb\x8d\xcb\x59\x65\xb7\xe2\xf9\x72\x0f\x1f\xf5\x22\xd6\x4d\x7f\xed\x8c\xfa\xee\x30\xb0\x0d\x15\x79\xf8\x8e\x71\x63\x2d\xfe\xd1\xeb\x8f\xcb\x40\x77\xeb\xe2\xd8\xc7\x83\xe2\x1f\x9b\x40\xfe\xb7\xd3\xc9\xcf\x74\x74\x51\x21\x6c\x87\x11\xd1\xaf\x85\x4f\x6c\xc6\xb0\x8a\x6f\xa3\x79\x53\xd2\x8d\xed\xc8\xe6\x59\xb6\x03\x24\xfa\xc8\x04\x3d\x92\x1f\x0e\x7e\x3e\x9b\xda\xdc\xdb\xee\xf3\x81\x0d\x71\xf8\xd2\x5e\xf2\x33\xe3\x43\xea\x7a\xc0\x46\xd0\x77\x58\xf2\x0b\x96\xfa\xe1\xca\xd0\x5f\xb9\xb2\x9f\x7e\x7e\x93\x19\x11\x7d\x77\xf4\xc8\x0f\xb7\x43\x6e\x12\xdb\x6d\x64\xe3\x9f\x13\x0e\x59\xdf\xaf\x6a\xff\x9d\xd7\x2a\x84\xef\x70\x70\x75\x86\x5f\xd6\x00\x1f\x36\x0f\xb3\xae\xbb\xaa\xed\xe7\xd4\xdf\xfd\x38\x15\xa1\x4f\x88\x10\x6d\x12\x3e\x42\x5f\x6e\x0b\x59\xf7\xf1\xd3\x7d\xad\xbb\xfb\x3a\x9f\x36\x2f\xbe\xae\xff\xd9\xca\x91\xfc\xee\xf5\xd6\xa3\x89\xfc\x07\xe7\xb1\x9d\x28\xdf\xfb\x56\x5b\xdc\x34\xe5\xeb\x68\xd9\x74\x8e\xfa\xa2\x10\xda\x6d\xd8\x56\x15\x54\x21\x6a\x87\xc3\x1f\xf5\x5b\x97\xdb\x8e\x24\xfc\x23\xce\x8f\x90\xa1\xaf\x13\xe7\xe3\xa3\xbf\xb6\xb1\x1a\xd3\x6a\x11\xc8\x77\x47\x87\x1c\xbe\x0e\xa1\xef\x07\xf6\x26\xc3\x2f\xa7\xfc\xc5\xee\xdf\x4d\x9d\x90\x9f\xa9\xd3\x1f\x06\xb8\xe8\xbf\x17\xe0\xae\x19\x17\x4e\x7d\x02\x5c\x02\x3d\xc2\xe0\x57\x80\x8b\x91\x47\x62\xeb\x87\x7f\xf9\x46\x12\x47\x02\xfc\xef\x06\xb8\xbf\xcd\xeb\xef\x54\x72\xbf\xe3\x7f\x90\xa8\x13\xbf\x4d\x8c\xef\x64\x12\xdf\xb1\x3f\x48\xbc\xa1\xdf\x46\xcf\x77\x24\xc1\xef\xbf\x1f\x3d\x1f\x71\x08\xfe\x6d\xe1\x20\x8a\xc3\x24\xfc\xa3\x44\xfd\xb7\xe0\x48\x14\xfd\x51\x9d\x81\xc0\x7e\xa7\x6e\x40\x84\x64\xfc\x07\x75\x00\xf2\x77\xea\x18\x51\x10\x40\xd1\x1f\xd5\x01\x88\xdf\xc6\xff\x61\x44\x92\xe1\x1f\x90\x4f\xc1\xbf\x85\x0f\x12\x3c\x0a\xfe\x08\x1e\xff\x9d\x64\xe4\x8e\xc6\xd4\xef\xc3\xff\x99\x75\x83\xec\x00\x13\x0e\xf4\xfb\x7a\x8f\xfe\xcb\x92\xc1\x3f\xcc\xfe\xaf\x56\x0b\xbe\x77\xac\xd4\x3e\x9a\xbc\xfe\xe5\x5b\x98\x0c\x49\xf9\x4f\x85\xc5\xff\x5e\x55\xb1\xf9\xbb\x2c\xf8\x77\x59\xf0\xef\xb2\xe0\x5f\xab\x2c\xb8\x66\x58\x7f\x5a\x59\x10\xdf\xf2\xbd\x35\xea\xa3\x8e\x64\x04\x1e\xe0\xdd\x56\xec\x23\x8e\xd4\xe1\x93\x07\x43\xdf\x63\xac\x2d\xe9\x5a\xe3\x1d\xf2\x13\x78\xad\xd1\xfb\x1a\xd6\x7f\x95\x05\x3e\x79\x21\xbc\x86\x1f\xe4\x0e\xdd\x62\xc4\xdd\x1a\x4b\xad\xd9\x17\xb5\x23\xb6\x8f\xe9\x89\xcf\x0d\x43\xdb\xcd\x07\xc4\x0e\xfd\xdc\xcf\xb3\x23\xb6\x18\x0c\xd9\xc2\x8c\x1d\xb6\xc5\xf7\xf8\xee\x93\x23\x6c\xc0\x07\xf4\x33\xf9\xf0\x85\xa4\x5d\x93\x95\x35\x24\x21\x3e\x79\x52\xb4\x85\xa7\xeb\x1f\xfc\x75\xcb\xc2\x07\x18\x5d\x2a\x74\x8b\x58\x22\x70\x2b\x84\x60\xbb\x35\x88\xc2\x77\xdb\x9d\x45\xbb\xef\x39\xeb\x1a\x34\x6f\x6d\xbb\x85\xcc\xf8\x56\x1f\x21\xa2\x2d\x8d\xdb\x42\x57\x78\xdb\x3a\xbe\xdd\xd3\x02\x7e\x02\x5b\xec\xf0\x49\x6e\xd6\xec\x03\xda\xc2\x22\xf8\x13\xf9\x6e\xfd\x44\x7b\x40\x76\x47\xfc\xb0\x61\x8d\xbe\xd2\xfc\x2d\x8c\xdf\x6d\x40\xbb\x2d\x31\x80\x37\xa1\x81\x5b\x89\xf4\xb0\x95\x48\xbf\xaa\xa8\xc4\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\x7f\x57\x51\xff\xae\xa2\xfe\x5d\x45\xfd\xbb\x8a\xfa\x77\x15\xf5\xff\xc2\x2a\xea\x13\xf9\x6b\x7d\x2b\xbd\x9e\x7e\xfe\xc0\x12\x49\x7d\x9e\x46\xfd\x0e\x08\xcf\x9d\x9e\x56\x2b\xf8\x52\xe8\x18\x77\xca\xe4\x05\xe6\x54\xf8\x8c\x29\xe9\xe7\x0c\x1d\xdf\x1a\xc2\xb5\x37\x54\xd5\x45\x9d\x0c\x81\xd1\x66\xa5\x13\x3f\x62\xbc\x0f\x8e\x20\xda\x50\x92\x12\x99\xbc\x58\x8d\x4e\x1a\x78\x61\xe8\xc5\x75\x0c\x87\x9e\x36\xe9\x41\x26\xce\xd1\x92\x84\xdd\xf2\x5e\x90\x21\xa1\x28\x02\x05\x5d\xd3\x3c\x15\x6e\x8d\x45\x49\xd8\xa3\xd1\x09\xb7\x54\x9f\x48\xc0\x87\x49\x9f\xde\x54\x84\xb8\x53\xeb\x0c\x51\x52\x55\xe1\xdc\x52\xf3\x15\xdf\xf7\xa7\x33\xd9\x04\x7a\x72\x9f\x9f\xb1\xce\x71\x98\x5f\x65\xd8\x08\xe3\xa3\x5a\xf0\x59\x43\x9e\x3b\xae\xeb\xf9\xcb\x4d\x60\xdf\x83\x06\xa0\xfd\xf9\xa6\x89\x27\xf0\x8a\x51\x1c\x46\x7a\x00\x0b\x13\x81\xa0\xd1\x0a\xe2\x75\x59\xd5\x8e\x23\x26\xb2\xb3\x86\xee\xfb\xa5\xdf\x5f\x94\xce\x68\x6d\x7d\xd2\x8d\x09\xbf\xa9\x74\x63\x3c\x18\x7a\x24\x2e\xfb\x90\x77\x58\x55\x35\xd2\xd7\x9c\xb6\x7b\x45\x68\xa1\x6c\x1f\x8b\x31\x19\xd6\x01\x68\x54\xde\x85\xba\x28\xf8\xd9\x4f\x47\x7a\xb8\x08\x37\x59\x6e\x66\xc4\x41\x51\x36\xd5\xee\x03\xe1\x4f\x64\xa3\x9c\xf6\xa5\xcd\xa7\xc3\x22\x90\x7e\x9c\x2d\xfb\x1a\x85\xda\x9a\x16\x4d\x11\x4b\x6d\x7e\x64\xcb\x25\x3b\xc5\x43\xd7\x09\xd3\x5d\x9b\x7d\x19\xe4\xeb\x73\xb3\xc8\x32\x96\x88\xd1\x1d\x7a\x9d\x1a\x48\xbc\x4c\xdd\x63\x94\xf6\xcf\xfb\x50\xa1\x29\xe0\x42\xaf\xee\x9c\x26\x6f\x9f\x87\x2d\xef\x6c\x49\x0a\xb5\x77\xc1\x47\x01\x56\xac\x95\xd1\x13\xe7\xa5\x86\x9c\x86\x9a\x37\xdd\x5e\x08\x36\x18\x32\x9b\xcb\x46\x61\xd9\x5e\x1c\x41\xfb\x34\x8a\x32\x48\x38\x89\x7a\x25\xf7\x52\xca\xb0\x71\x84\xe3\xaf\xb3\x71\x52\x45\x6a\x0f\x69\xd2\xd3\x9e\xcb\x69\x3a\x75\xbd\x8b\xa7\x7c\x7e\x95\xfa\xbd\x86\xce\x8f\xd8\x4d\xbb\x19\x9c\xaf\x55\xac\x3d\x84\x25\x1a\xe5\x87\x0f\xaa\x36\xa1\x2a\xdd\x5e\x7a\x34\x56\x10\x43\xb8\xd0\x48\x13\x12\x02\x34\xc8\xdd\x08\xc1\xf7\xea\x36\x7e\xd2\x0f\x5b\xe5\x2e\x0f\x09\x5b\xf4\xf4\xde\x30\xad\xd9\xc4\x59\x26\x66\xb7\xd3\x9d\x61\x6c\xa0\x16\x69\xd1\xec\x26\x57\xba\xa4\x58\x79\x85\xb5\xee\x2d\x61\xb1\x02\x5a\x0c\x26\x9f\x17\xa5\x89\xcb\xe6\xe5\x05\x17\x3e\xe8\x74\x71\xe9\xe4\x17\x96\x8a\x88\x85\x71\xda\xa3\xa7\x65\x4c\x7b\xc8\xe7\xbb\xee\xcb\x12\xd8\x14\x4c\x61\xc5\x49\xc5\xe6\x56\x6a\x01\xef\xc2\xd0\x14\x2b\xd1\xbb\x89\x79\xa0\x8a\xc5\x8e\x77\xa1\xe3\xc1\xe2\xfd\x7a\x79\xc4\xcd\x51\xeb\x9e\xf2\x4a\xd5\x9b\xe1\x92\x50\x79\x30\x5e\x68\x24\xa7\x35\x63\xf6\xf1\xc1\x9d\x58\x1c\xb2\x7d\x14\x5a\xae\xb3\x16\xf9\x19\x0e\x18\xac\xe6\x19\xc3\x92\x63\xb1\x89\x50\xf5\xc9\x79\x41\x8c\x3d\xf7\xaa\x48\xd3\x66\x2b\xe0\x5d\x18\x26\x68\x2e\x73\xd0\x9b\xb8\x54\x58\x2e\x30\x71\xe5\x42\x56\xcb\xdd\x4b\x25\xef\x19\xbc\xf5\x28\x70\x4f\xd3\x06\x77\xa2\x5d\x22\x76\x41\xbf\x5e\xd2\x3f\xf7\xd1\x36\xd5\x13\xfd\x8b\xf9\x0e\xe6\xc7\xa3\x6d\x0a\x8a\x7a\x83\x10\x6d\x4f\x04\xf5\x6c\xdf\xd7\x77\xff\x70\xba\x30\x4a\x82\xb0\xbe\xb5\x28\xe7\x9b\x27\xab\x51\x33\x9c\x4b\x5f\x04\xf1\xae\xf7\xf4\xbd\xa1\x81\xbd\x74\x47\x99\xa6\xd8\xb3\x20\x7b\x9f\x1c\x93\x63\xb2\xbd\x04\x6b\xaf\xdb\xf2\x7e\x5a\x10\xe7\x0c\x61\x67\x23\xd6\x59\x8f\x2a\xd2\xb2\xca\xf6\x5c\x26\x51\x5b\x53\xf1\x95\x40\xea\x0b\x89\x39\x00\x43\x9d\xc0\x13\x41\x5e\x94\xb8\x03\x14\xae\x34\xa0\x5e\xf5\xe7\x50\xa2\x53\x89\xaa\x29\xea\xe2\x4e\x4d\x42\x22\x75\x91\x2f\x54\xc6\x71\x41\x82\x20\xe0\x79\x98\x14\x94\xbc\x60\x90\x37\x55\x40\x52\x6b\x9d\xac\x87\xce\x48\x67\x20\x1f\xe1\x85\xff\xf4\x82\x8e\xd2\xeb\x12\x16\x19\x16\x84\x4f\xef\x87\x8a\xf9\x44\x86\xea\xe4\x9e\x10\x3a\x49\x70\xce\x28\x75\x79\x4f\x76\x5d\x12\x7d\x24\xc5\xf7\x6c\xd8\x33\x12\x37\xec\xef\x4c\xf4\x20\x9e\x40\xe7\xa9\xfa\xbb\x85\x4d\xcf\xb9\x8e\xe8\xc5\x83\xed\x5a\xb8\xbe\x3d\x36\x0c\x7d\xa2\x7b\xaa\x2d\x0d\x21\x02\x67\x71\xf4\xc5\x40\xd3\x33\x2f\xda\x67\xa5\x05\x75\x3d\xa3\xd8\x82\xb7\x5a\xfd\x5d\x4d\x13\xbf\xc0\xe5\x3b\x40\xde\xf5\x93\xee\x10\x11\x0f\xe2\x34\x36\x32\xe6\x59\x25\x4a\x21\x34\xb1\x56\xb5\x8f\xe7\x45\x6f\x3c\xe6\x6d\x5c\xb9\xa8\x12\x04\xcd\x22\x72\x44\x35\xb9\x65\xd1\xd9\x11\x18\x86\x80\xcc\x0b\x7b\xcf\x5e\x8c\xa9\x82\x50\x86\xc9\x86\x73\x74\x52\xc4\xa7\xa8\x5f\x2f\xf4\x79\x9a\x12\x25\x7c\x9b\x29\x5d\xf8\xfd\x83\x89\x4f\xa8\x88\x35\xee\xd9\xf5\x6c\x17\xa2\x7c\x05\xf5\x5e\x7d\x4d\xab\x42\x56\xbf\x20\xe6\xe5\xfa\x69\xe0\x43\x2a\x7d\xa2\x2d\xe3\x92\xdb\x14\xbe\xc8\x4b\x61\x13\x78\x35\x26\x59\x70\x19\x26\x3c\xa3\x7a\x75\x20\x64\x41\x43\xcc\xe6\xa9\xa0\xcd\x95\x96\xd0\x93\x99\xa1\xa3\x55\x22\x14\x35\x95\xc1\x1e\x04\xfd\xd0\x44\xe6\xb7\xb4\xa8\x94\xb5\x58\xaf\xf4\x7c\xae\x1b\x39\x2a\x4a\xf1\x7d\x02\x49\x36\x3a\x3f\x6a\xa6\x53\x14\xb6\xb5\x78\x51\x7c\x5a\xee\x79\x38\x75\x9c\xac\x35\x42\xfe\x7c\xb6\x67\xb0\x2f\xa5\x96\xe3\x6c\x96\xa5\xaf\x6a\xc9\x18\x85\xd6\x07\x19\x3f\xe7\xb7\x6b\xa4\xb4\x95\xc0\xc8\x81\x31\x05\x97\x02\x43\xae\xe5\x29\x91\x0b\x95\x00\xe9\x07\xdd\x34\x6c\x9a\x31\x97\x82\x6a\xe5\x4e\x1a\x5e\x9d\xfe\xb2\x50\x81\x09\xcc\xfa\x6c\x99\x1e\xd9\x3d\x60\xee\x92\x21\xa5\xc0\x60\xc6\x08\xdf\x34\x41\xc6\x14\xb3\xc1\x47\xb4\x95\x3b\x38\x4d\xe9\x65\x1e\xf3\x98\x56\x35\x80\xea\x25\xdd\xba\xa5\x25\xa3\x70\x17\x4c\x10\x90\xca\xe4\x90\xf1\xc4\x53\x2f\xc7\x1c\x9a\xd3\xdb\x7e\xde\xeb\xbd\xcd\x1b\x32\x08\x10\x56\xd6\x8d\x61\x73\x3a\xe3\x8f\xf8\x44\x9a\xb7\xc9\x62\x31\x22\xb3\x1c\xfe\x1a\x12\x09\x06\xc0\x3d\x28\x4c\x2f\xfd\x74\x6e\xc6\x3d\x99\xdf\xd0\xd2\xf7\x61\x43\xec\x91\x3c\xce\xa4\xe9\x42\xf8\xc4\x93\xa4\xe9\x91\x56\x58\xf1\x26\xf3\x3a\x23\xb2\x7f\xba\xaf\xf8\x8b\x3d\x75\xf7\x67\x9c\xd1\xfe\xf8\x21\xc7\x3e\x34\xe3\xf2\x55\xd5\x36\x13\x36\x01\x68\x27\xb6\xc1\xe5\xb6\xc8\xb2\xd0\xfe\x5c\xbd\xb3\xa9\xf1\x3a\x20\x65\x06\xef\x9c\x13\xa8\x74\x47\x69\x07\xf4\x91\x56\x93\x05\xd0\xb7\x03\x89\x7d\x35\xd2\xfd\x91\x3a\x56\xc6\xe7\xa2\x80\x76\xdc\x25\xbe\x00\xf7\x4b\x72\x09\x2c\xb9\xcb\x13\x4c\xbc\xf5\xc4\x73\x59\x90\x04\x88\x88\xa5\x93\x45\x29\x90\xd0\xa1\xa6\x9e\x7b\x40\x47\x32\x34\x41\x03\x5c\x1f\x70\xbe\x31\x18\x2e\x9f\x09\x1d\x7b\x47\x90\x0e\x79\x1d\xee\xe9\xa4\x8a\x25\x0f\xaf\xc1\xed\xf3\x3e\x76\xc3\x3e\xa9\x92\xab\x18\x3f\x07\x2d\xce\xb5\x84\xf2\x07\x43\x49\x50\x26\x47\xf5\xea\xfa\x34\xab\xf9\x45\x56\x04\xf4\x7e\x12\x28\x33\xc9\x02\xdc\x8d\xd2\x69\xa0\x9b\xfd\x1d\x28\xa1\x2b\xec\x3f\xc1\x25\x4a\x4e\xf9\x72\xbf\xdc\x02\x60\x32\xeb\x3b\x63\x66\x22\xca\x1a\x2f\xda\xcf\x1b\xc6\x4d\x3c\x6e\xa6\x49\x2e\xc7\x93\x1c\x8a\x12\x8f\x85\x3c\x66\x7c\x5f\xbd\x93\x7e\x82\x07\x17\x8f\x22\x86\x61\x54\x09\x67\x5a\xcb\xe6\x8d\x25\x28\x44\x05\x9f\x18\xb0\x1b\x1e\x33\x33\x99\xda\x14\xb3\x5d\x04\x7b\x77\xd2\xa4\xae\x73\xe0\x5e\xb9\x4b\x0a\x5f\x1f\x77\x27\x1e\xf1\xec\x25\x35\x3c\xc5\xc0\xe2\x54\xf0\x9c\x5b\x2a\x27\xa2\x45\x93\xae\x4b\xe0\xc2\x7a\x82\x0d\x67\x26\xcb\xdb\x18\x59\x49\xa2\x91\x46\x3c\xbd\x41\xa0\x92\xd5\x8a\xc7\x90\x57\x03\x23\x2e\xba\x1f\x31\x6b\x6f\x60\x4d\xd6\x84\x94\x87\x74\xe9\x29\xbd\x90\xb6\x62\xd0\x2c\x4b\xa4\xea\x44\x55\xb2\xa1\x23\x20\xef\xe2\x15\x7f\x7a\xfa\x39\x39\x45\x67\x3e\x5e\xd4\x3e\x7a\xdc\x0b\x39\x7a\x5f\xef\xd5\xab\xca\x05\x9f\x99\x58\x01\x90\xe2\x7d\x1a\xcc\xf2\x79\x6c\x8c\xc7\x29\x7e\xd3\xd8\x80\x9e\x64\x82\x7d\xa1\xa8\xfc\xb8\x69\xee\x33\x48\x83\xd7\x93\x30\x68\xb6\x68\xc1\x13\xb5\xd4\x2e\x82\x63\x79\x00\xa3\xdc\xd2\xf0\x5c\xb3\x5c\xce\xe1\x89\x4c\x9c\x4e\xb4\x32\xef\x74\x1d\xb5\x77\x10\xd5\xad\x48\xbc\x70\x65\x69\xf9\x3e\xa0\x4b\x4d\xaf\xa8\x8c\xe0\x2c\xcb\x79\x28\x33\xab\x16\xcf\x27\x27\xed\x45\x0b\xb6\x3a\xc3\xa5\x21\xb3\x94\x1b\xd0\xc3\xf0\x1a\xf6\xf6\xb8\x71\x2a\xaa\x82\x0b\x8a\x49\xa0\x5c\xd5\x79\xb9\xb3\xbc\x6f\x01\xe6\xdd\x65\xfe\x7d\x70\x17\xc8\x4e\xf7\x8b\xcd\x45\x0f\x55\x57\x2b\x30\x43\x9e\x13\xff\x10\xaa\x00\x61\x43\xa9\x67\xfb\x98\x68\xd4\x08\x54\x14\xe8\x96\x56\x7c\xf9\x14\xcf\x9d\x8b\x30\x7b\x08\x3b\x49\xa2\x26\x5d\xdf\xaa\x2f\x95\x97\x13\x91\x83\x36\x0a\x69\x6f\xa9\x36\xf9\xb9\xf4\xc3\x1e\x35\xb1\x97\x11\x1a\x4c\x40\x67\x14\x76\x77\xe4\x1b\x5b\x3f\x0d\xb6\x0e\x29\xee\xed\xde\xe6\xb7\xc9\x9b\x16\xae\x71\x89\x3d\xee\xe7\x53\xe0\x65\xc4\xbb\x43\x59\x94\x21\xe7\x3d\x35\x14\x63\x4d\x14\xa3\xac\x99\x4f\xae\x09\xa8\x20\x17\x64\xc6\xaf\x85\xbd\x19\x99\xfc\xcb\x80\x13\xa8\x42\x4c\x92\x61\x52\x7a\xa6\x8a\x85\x9a\x5b\x96\xc7\xff\xe4\x47\xe8\x35\xf1\x5f\xec\x47\x60\x73\xec\x67\x8e\x52\x7c\x7e\x81\x03\xa8\xc2\x1e\x11\xee\x3c\x24\x9b\xa6\xfd\x74\xfd\x2c\xa1\x15\x8d\xb1\x4d\xdb\x99\x89\x68\xa6\xec\xe2\x82\xcb\x2e\xb0\x57\xc2\x0e\x94\xf4\x56\xe8\x73\x34\x55\x98\xd0\x7e\x09\x81\xdd\x7b\xfc\xd5\x96\x59\x3f\x00\x1f\x16\x36\xdf\xe0\xdb\x05\xc3\x88\x10\x53\xab\xab\xf7\x4c\x2b\x4e\xaf\xef\x97\x88\x78\x2c\xb5\x2a\x4a\x9a\xaf\xe7\x60\x9c\x60\xf6\x50\x3d\x2f\xe6\xf4\x7c\xf0\x40\x11\x6a\x2f\x17\x04\x31\xce\xe9\xc9\xab\x3b\x42\x27\x02\x23\x6f\xf7\x42\x48\xb5\xf4\x5c\x75\xf3\x64\xe9\xe6\xe3\x2c\x3d\x40\xe3\xea\x02\x26\x97\xfb\xa2\x27\x86\x04\x57\x22\x30\x90\x78\x6f\xa7\x8d\xc1\xd4\x62\x27\xaa\xca\x5f\x2c\xd8\x34\x6c\xfc\xc4\xa9\x14\x33\x80\x0c\xbf\x28\x1a\xd8\xcd\xd8\x5c\x4b\xc5\xb8\xa8\xa3\x3d\x66\xb0\x30\xaa\x71\x14\x72\x39\x7b\x33\xbc\xb2\x78\x09\xec\x93\x6f\xf4\x2b\x30\xe6\x19\xe4\x3f\x14\xa9\xa6\xb5\x88\xdb\x03\x76\x40\x85\x3d\x32\x9e\x4b\x71\x78\x33\x37\xb6\x4a\x3a\x78\x6f\xe1\x2a\x8f\xa5\x68\x23\x96\x37\x8a\x06\x24\x02\xf4\x58\x2e\xcb\xb8\x64\xd2\xb5\xab\x50\xb5\xe3\x99\x19\xa3\xba\xf7\x0a\x81\xc4\x1d\x4b\xbb\x4d\x4e\x0f\xf6\x85\x62\x89\x35\x13\xbd\xca\x5a\x43\x4f\x0d\x6b\x48\x81\xd4\x4b\x03\xa1\xd8\x4d\xa3\x5e\x52\x83\x78\x11\x98\x42\xd3\x21\x46\x31\x54\xca\x32\x27\x4b\x4e\x5f\x49\x65\xbe\x29\xb4\x52\xe5\x8a\x83\x51\xf6\xae\x92\x75\x48\x5c\x4f\xbe\x68\x68\xca\x93\x2e\xec\x22\x0a\x71\xfc\x3c\x8b\x8c\x20\xf0\xae\xe9\x28\x18\x91\x0a\xfc\x09\x7b\x3d\x48\x65\x1a\xa3\x00\x7e\x59\x08\x7f\x0b\xfa\xb4\x5a\xe8\x11\x46\x63\x13\xf0\x8c\x74\xec\x5a\xd6\x62\x1e\xba\x14\xbb\xa1\xdd\xf0\xb0\x7d\x56\x98\xda\x21\xe9\x08\x88\x72\xf7\xd4\xca\x14\x90\x96\xae\x52\x73\xb8\x0c\x0f\xa9\xde\x2e\xed\x25\xbe\x18\xf1\x3d\x31\xa0\x08\xb8\x66\x72\x73\x4d\xb9\x9a\xa2\x11\xd9\xe6\x39\x00\x83\x63\x14\x9b\xa2\xec\xd6\x0e\xcd\x9b\xc3\x99\x3b\x70\xc3\xc1\x77\xee\x20\x06\x75\x03\xc0\x30\x14\x6d\xa8\x6f\x9e\xbe\x58\xdc\x79\xd3\x32\x10\x27\x6c\xd5\xb1\x04\x5f\xe5\xab\x91\x68\xb3\xb2\x1a\xdd\xf7\xdc\x19\x8c\x9b\x37\x41\x29\x77\x46\xe5\xf9\x98\x7c\x88\x2d\xd0\x1b\x88\x5f\x12\xfa\x59\xd0\x84\xb0\xe7\xbd\xdc\x81\xdf\x39\x7b\x27\xc9\x7b\x33\x78\x19\x13\x36\xc0\xf0\xd2\x91\x0e\x84\x81\x9b\x5f\x9d\x85\xd7\xb5\x58\x7c\x08\x07\xc5\x86\xea\x79\x35\x14\x64\x32\x33\x01\xed\x1d\x7b\x9d\xd0\xdb\x4e\x55\x57\xb3\xe5\x88\xe9\x05\x1d\x50\x45\xa5\xe9\x87\x99\x56\x97\xbd\x75\x3e\xe7\x7f\xba\x4d\xff\xc5\x9e\x86\x97\x74\x3f\x7f\xbe\xf5\x01\x49\x27\x9e\xb7\x81\x9c\xe8\x89\x1b\x8c\x24\x64\x27\xa6\x75\x22\x1a\xfa\x88\x64\x37\xae\x28\x32\x23\xb7\xfa\x51\x35\x4c\x3e\x0c\xd0\xde\x4e\x9f\x4e\xc9\xbe\x07\xde\xc8\xfa\x77\xc1\x36\xee\x2b\x32\x0c\xb0\xb9\xd2\x81\x2f\x6b\xaf\xf3\x9c\x8a\xfc\x98\x9e\x58\x8b\xc1\xe5\xba\x26\x12\x2f\x8a\x3d\x40\xac\xe2\x93\xa3\xbb\xbe\xa0\x23\xe9\x48\x90\x10\x81\x00\x43\x35\xf8\x85\x61\xb4\xf4\xa8\x0d\x51\xf1\xa2\x70\xbb\x9e\x25\x3e\x23\x80\x18\xed\x88\xde\x8e\x01\x72\xde\x93\x98\xbe\x0f\x3d\xcb\x43\xd3\x77\x91\x49\x78\x7d\xf6\x75\x97\x50\xde\xde\x93\x91\x61\x7f\xca\xad\xc6\xca\xb2\x1e\x65\xfa\x17\xa4\xe9\xcd\x9d\x4b\x5e\xf1\xfb\x86\xdc\xd0\xa8\x24\x38\xf4\x8c\xd8\x1d\x8d\x39\xb3\x43\x97\xd5\xb9\x79\xf7\x14\x7d\x87\x6f\xf4\x13\x2a\x23\xd6\x40\xea\x57\x9a\xf7\x72\x15\xfa\x48\x09\x30\xa7\xbd\x5a\x9f\x54\x4a\x74\x14\x1d\x74\x47\x44\xd6\x68\x04\x61\x8d\xc6\x30\x6a\x85\x44\x50\xe1\x41\xa0\xba\x2d\x16\xb4\xc6\x4b\x05\x6b\x59\x6d\x40\xa6\xc6\x2b\xf5\xaf\x52\xc4\x80\xba\xd3\x7a\x0c\x02\x91\xa2\x54\x9b\x39\xeb\xb8\x6c\xf1\x34\x05\xba\xdd\x3f\xb0\x54\x2e\x69\xb4\x83\x29\x31\xcd\xd0\x18\xec\x40\x54\x90\x3b\x4a\x37\x5e\x02\x6a\x0b\x69\x5f\x59\x3c\x4d\xd2\xcf\x24\xe0\xcb\xbc\x74\x43\xdf\x74\x66\xa0\x6c\xeb\x16\xd0\x20\x83\x29\xa6\x8e\xd7\x04\xf4\x31\xe9\x53\x94\x46\x0c\xc4\xde\x9c\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\x3b\x91\x89\xb1\xbc\x81\x57\x0e\x0c\xb0\x4c\xb9\xba\x53\xb3\x1a\xaf\x2c\x3f\xdf\xaf\x93\x7c\x6e\xcb\x6b\x3b\xc3\x20\xd5\xc2\x63\xad\x0a\xcc\xd5\xd7\x6e\x8f\x08\x68\x94\x8e\x4a\xf5\x41\xb9\x4c\xfb\x6c\x72\xce\x92\x6c\xc1\xbe\x8b\x3d\xd9\xd0\x9a\xcf\x57\x51\x95\x09\x02\xbb\x90\xce\xcc\x8c\xdc\x39\x86\x95\x2b\x57\x02\x1e\x96\x93\x03\x62\x11\x9a\x33\x52\xc3\x39\xc4\xa0\x4e\xba\x72\xbc\x3d\xf2\x22\xad\xb1\x13\x0c\xbc\x3d\x9e\x17\x84\x3f\xf3\xe9\xf6\x4d\xdc\xfd\xc5\xec\xee\xf9\xc3\xee\x8a\x05\x92\x24\x88\x37\x26\x60\x4f\xb0\x01\x7e\x2e\x5e\xb3\x9f\x9f\xc9\x48\xe6\x9f\xb4\x11\x32\x86\xc0\x55\x60\xeb\x5c\x5a\x81\xb1\xa8\xb1\xc3\xe4\xcb\x35\xe5\x45\xac\x1b\x27\xa7\xbc\xed\x3d\xbe\x96\xb5\x5c\x4a\x33\x5f\x9e\x26\xac\x1e\xf9\xa7\x24\x79\x41\x6e\xd1\xa9\x2c\x56\x6a\x0e\xc6\x30\xd2\x93\x7b\xe4\x4a\x5c\x82\xdb\x99\x57\x15\x91\xaa\x2a\xbd\xd6\x80\x11\x1a\x18\xbb\x79\x2a\xba\xa6\x65\xa6\xeb\x9d\x2e\x33\x97\x82\xf5\x44\xc2\xd7\xfc\xdc\xdd\xf4\x52\x77\x1a\xed\x79\xef\x22\x38\xba\x36\x5d\x74\xea\xa6\x09\xc4\x8b\xd8\x7b\x5a\x06\xc0\x0c\x8b\xcc\x5b\xb7\x45\xe2\x2a\x7a\xc1\xe7\xbd\xd6\x3c\x2e\x8f\x27\xa7\xde\xf2\x97\xa9\x4b\xa9\xd6\x08\xb3\xab\x92\xdc\x5b\xb6\x1d\x22\x98\x2e\xfb\x34\x7a\xa2\x29\x41\x2f\xd5\xab\xa7\x63\x47\x7b\x5d\x52\x05\x5e\x60\x09\xcd\x63\x88\x01\xc7\x34\x99\xd3\xcb\xdc\x01\x6f\x45\xc1\xc2\x5e\x19\x69\x89\x4b\x69\x2a\xf6\xf7\xca\x9e\x2b\x7a\xce\xb8\xb0\xef\x42\x4d\x99\xd6\x4c\xcb\x48\xbd\xbc\x68\x71\x94\xda\x4e\x4d\x49\xba\x10\xdb\xfe\xa6\x6a\xb6\x6a\xaa\x85\xf2\xe2\xf7\x86\x58\x36\x69\x39\x94\x34\xd1\x4b\x17\x5a\x1e\x6e\xc1\xc3\x04\x5f\xe7\xc2\x7e\x00\xde\x29\x01\x99\xab\x14\x95\x8e\x2c\x97\xef\xbb\xdc\x3e\xa8\x17\x4d\xa6\x34\x3e\xbe\xac\xf3\xa2\x07\x5e\xf9\x26\x8a\x19\x00\xba\x58\xe1\xed\x7b\x30\xb6\xcc\x83\x9f\x6c\x41\x74\xdc\xf0\x4a\xd0\x93\x15\xa0\xf0\x09\x56\xd4\xfb\x85\xab\x86\x18\x19\xe5\x90\x30\x69\x55\xf1\x47\x95\xac\xbb\x96\x9c\xce\xc0\x93\x4f\x08\x00\xd1\x2b\x1d\x4e\xc4\x01\xe1\xf6\x54\xdf\x86\x08\xe6\x82\xa1\xa4\x35\x34\x61\x56\x0f\xcf\x3a\xb5\x27\xf0\x8e\xdd\x80\xca\xb6\x6e\xa0\xf4\x86\xcf\x55\xcb\x74\x1c\x09\xb6\x24\xf0\x16\xe7\xc5\x6d\x15\xe1\xca\x61\xb3\x6d\xb0\xe1\xdd\x66\x4e\x25\x15\x23\xa4\x32\x14\x31\x77\xf5\xa4\xfe\xe4\x30\x0d\x58\xec\xc3\xb0\x03\xf1\xd7\x65\x3f\xd3\xba\xe8\x8d\x09\x10\xd1\xe8\x78\xa1\x74\x0d\x45\x1f\x32\x27\x12\xa0\xd8\xf4\xa9\xb4\xe4\x70\x67\x80\x60\xd5\x12\x00\x52\x3e\xc7\x9a\x61\xd2\xc7\x0d\x21\xe4\x22\x86\xac\x2c\xeb\x30\x6f\x61\x24\xa1\x04\xfa\xbb\xd0\xd5\xf9\x15\x28\x85\x94\xe6\x69\x1b\x00\x52\xbc\x18\x62\x91\x51\xff\xd4\x27\xb5\x35\xdd\x5f\xec\xe7\x97\xa3\xf3\x4f\xbb\x6b\xdb\x81\x86\x78\x7b\x7a\xef\x6f\x8f\x22\x0e\xdf\x77\x41\x76\x38\x08\xe6\xdf\xbe\x65\xf2\x8a\x0f\xdf\x8b\xd3\x9e\x51\x5b\x25\x32\x02\x6b\x6c\xdf\xd6\x72\xcb\x51\x82\x7f\x9c\x79\xa3\xe0\x33\xbf\x10\xca\xcc\xb7\x9c\x4e\x78\xc6\xaf\xcb\xeb\x59\x10\x10\x51\x22\x0f\xf9\x56\xe5\xec\x1e\xab\x6e\xe5\x32\x00\x2d\x41\x61\xe3\xc2\xf6\x51\x64\xd4\xd1\x82\xf8\x89\xc9\x3c\x50\xf9\xb4\x80\x80\xf9\xbe\xdc\x12\x58\x6b\x6f\xba\x0e\x83\x0d\x8c\x61\x8b\x81\xf0\xf4\xb4\xf0\x34\xbb\xc7\xfb\xe5\x3a\x42\x88\x88\x5e\x05\x83\x0e\x0a\x1a\x60\xdd\x4e\xf2\x43\x1f\x94\x99\xcb\x7b\x22\xa4\x61\xe4\x8c\x57\x79\x72\xa0\x06\xf1\x27\xf9\x7a\x19\x66\xda\x1e\xee\x06\x7b\x7f\x55\x34\x92\xa0\x79\x31\x5b\xc0\x62\xd2\xf2\x70\x69\x3a\x22\x69\xac\x13\x9f\xde\xa4\xd3\x9b\xbd\x1b\xf4\x9d\x79\x31\x81\x6c\x18\x9c\x6c\x45\x06\xcd\x4f\x31\x99\x54\x0c\xad\xa5\x7b\xd8\x86\xd9\x41\x53\x8b\x22\xb5\x5e\x4c\xf5\x66\x27\x81\x21\xab\xfe\x91\x34\x67\xc6\x1d\xf9\x17\x6d\x46\x6d\x2b\x5f\xe9\x33\x2f\xbe\xab\x40\x7c\x3f\x5e\x32\xb4\x0c\x5a\x51\x9f\x50\xa6\x9b\x27\xb9\x84\x1d\xfb\x69\x4e\xd5\x03\x73\xf7\x13\x81\xbc\x28\x9a\x0f\x6e\x6f\x13\xd0\x38\x88\x3f\x97\xbd\xf4\xb4\x90\x9c\x3a\x1b\x39\xbd\x0f\xf6\x99\xf5\x22\x4f\xe3\xf9\x71\x6d\x95\xb7\x19\xb8\x79\xa7\x5f\xd9\x4b\x99\xf1\xb7\x1a\xd3\x08\xac\x55\xa1\x57\x9e\x56\xa5\xb6\x8f\x19\xa4\xdf\xef\x8d\xa0\xc1\x5c\xf4\xda\x85\xbc\xe7\x49\x6d\xde\x2e\xa2\x82\xea\x34\x08\xe6\xdd\xb5\xed\x71\xaf\x36\xdc\x06\xbc\x3e\xd4\x2b\x7d\x7e\xdd\x55\x6e\x02\xde\x33\x73\x8e\x02\x67\xb1\x34\xeb\x84\xde\x5d\xd0\xd8\xbf\x0b\xe9\x8e\xbd\xdb\x87\x99\xe7\x31\x31\xcf\x1a\xd1\x37\x9e\x85\xdc\x6a\x30\x49\x79\x50\xcb\x2f\x26\xad\x51\xa1\x01\x42\x04\x07\x29\xef\x9c\x60\x95\x52\x87\x79\xee\x8d\x98\x77\x82\x05\xf2\x6e\x71\xe0\xf0\xee\xd1\x40\x9e\x2a\x5c\x60\xe6\xd3\xbd\x4e\x85\xcc\x62\x9b\xe6\x04\x4f\x8e\xce\xba\x4c\x39\xca\x11\x4d\x8f\x8c\x07\xb5\x3d\x8d\x77\xc9\x7e\x53\xcc\x3f\x33\x66\xec\xfe\x62\x31\xe3\xfd\xf6\xeb\x9f\xfc\x7f\xf3\x10\x6f\xeb\x16\xb9\x54\x41\x78\x8e\x39\x99\x81\xd3\x92\x1f\x7d\x8a\x9f\xce\x7e\xce\xd8\xbc\xf1\x74\x60\xec\x95\x76\x8c\x77\x4f\xc3\x27\xdf\x79\x7d\xff\x90\xef\x7b\xfa\xce\xcb\x66\x1c\x5f\xe2\x8b\x78\x62\xcb\xd0\x77\xd8\x61\x96\xdd\x20\x7f\x5c\xe1\x2a\x7b\x3c\xb3\x82\xb0\x62\xe2\xff\x67\xef\xbf\x75\x35\x46\x9a\x2d\x41\xf4\x81\x68\x50\x2b\x93\x5a\x6b\x4d\x8f\x5a\xab\x8f\x9a\x4f\x7f\x51\x7f\x9d\x7b\xaa\x1a\x98\xc1\xe9\xc1\xd4\x00\x65\xb4\x41\x63\x6f\xf0\x5b\x4c\x64\x66\x44\xac\x08\xae\x48\x1a\x15\x49\xa4\x96\xb9\x42\xc2\xde\xb1\x49\x94\x5b\x57\x5d\x51\x14\x40\xd0\xad\x6c\x59\x8c\x40\xd7\xe8\xe7\x87\x33\xaf\x99\xf2\xd5\x8e\x7b\xbd\xd9\x37\xf8\x33\xa0\xe5\x7a\xa3\xdd\x15\xcb\x58\x15\x56\x5e\x79\xdd\xd9\x1b\xc3\x0f\xd2\xbc\x61\xba\xb2\x3c\x53\xab\xd8\x53\x59\xa1\x6d\x18\xf5\xf3\x79\xf3\xcd\xa7\x23\x98\x3d\xdc\x9e\x1a\x70\xfc\x99\x10\x29\xe3\xa6\x01\xd6\x30\x2a\x2e\x46\xb3\xc6\xbc\x77\xb6\x9d\xd2\x69\xa8\xd3\x11\x7a\x70\x36\x31\x29\x32\x79\x66\xdb\xbb\xba\xd5\x8a\x2c\x6b\x9c\x77\x6c\xee\x1e\x87\xa2\xed\x9c\x69\xc3\xd3\x2c\xfb\xf4\xdd\xe0\x75\xee\x86\xc1\x0c\x33\x34\x9c\xc3\x7e\x61\x0d\x01\x6c\x24\xb0\x31\x29\xb1\x13\xf4\x34\xb2\x1c\x6c\x03\x1c\xe4\xec\x29\x14\xca\x5b\x7e\x2f\x97\x8e\x96\x42\x27\x82\x74\xf2\xcf\x5d\x9e\x1c\xd7\x1d\x1e\x1a\xb7\xe8\xd5\x71\x29\xd6\xff\x8a\x0d\xb3\x55\x82\xd7\xe5\x92\x20\x8f\xfe\x38\x19\x26\xee\x72\x1c\x2b\x39\x3b\x14\x6a\x07\x8f\x95\xa2\x1b\x40\x08\x44\x3a\xbe\xb2\x92\x0f\x2d\x2a\xee\xf9\x75\xbb\xd1\xd1\x10\xf6\x42\x71\x67\x38\x62\x3d\xb0\xe4\xd8\x10\x8f\x28\xdf\xe2\x23\x6c\x81\x11\x42\xd9\x1c\x98\xac\x1e\x69\x13\xf5\x94\x68\x87\x7d\x6c\x64\x7d\x13\xe3\x3d\x50\xb0\x77\x11\x85\xc2\x13\x83\xd3\x71\x3f\x01\x2d\x29\x73\xd6\xdb\x94\x67\x2c\x6f\x6a\x76\x7c\x0c\x69\x2f\xd5\x4b\x3b\x73\xdc\xfb\xe7\x12\xf2\x60\x0f\xee\x6e\x31\xf1\x56\xa4\x37\xdb\xac\x73\x38\x83\xdc\xb7\xe7\x03\xf6\x4c\xf9\x04\x42\x8f\xd9\x1f\xc6\x82\xd0\x70\x7e\x9f\x74\xcc\x90\x57\xf1\xa2\x13\x02\x34\x7e\x16\xb8\x30\x76\xb4\xbf\x81\x66\xe3\x6c\xcf\xcb\xce\xea\xbd\x0a\x9d\x27\x7b\xbd\xdf\x1d\x7a\xbc\x0e\x94\xd7\x9c\x2f\xd1\x5c\x71\x38\xa2\x7c\xc0\x0d\x4d\x73\x37\x07\x7b\x8a\x15\x3a\xd4\x5e\xf0\xc2\x57\x57\x59\xa1\x39\xd6\xe4\x85\x0c\x00\xa4\x97\x67\x4d\xfa\x3f\xa7\x8e\xde\x35\x3f\x72\x61\xe0\x64\x26\xf3\x0f\xc7\xb2\x7f\x19\x87\x2c\xc5\xbf\xec\x90\xa2\x7f\x10\xc2\x24\xf5\xaa\x42\x5d\x38\x91\xc2\xd6\x86\xd6\x73\x93\x25\xcf\x0a\xe5\xda\x71\x02\xec\x2e\x42\xea\x96\xe5\x15\x34\xb9\x52\x3d\xa0\xbb\x93\x55\xd5\xae\xeb\x2b\x62\xba\xf5\x39\x27\x66\x3c\x77\xb2\x42\x72\xe3\xb5\xca\x79\xdf\x41\xe8\x71\xe1\x31\x42\x3b\x8c\x66\xf5\x08\x78\xdf\x57\xac\x6f\x9a\x4c\xaf\x48\x62\x95\x89\x53\x28\xb8\x03\xb6\x05\xd8\x9e\xa0\x28\x95\x9a\x96\xbf\xc3\x09\x15\x98\xe6\x9a\x69\x00\xed\x16\xa5\xf3\x75\x1c\xe3\x8d\x42\x1a\x72\x6f\xf4\x27\x2c\x5e\xcd\x4c\x57\xe5\xa1\x82\x1e\x3f\xf1\xcf\xeb\x0b\x5a\x5a\x2e\x2a\xed\x5a\xce\xe5\x28\x1e\x20\xad\x19\x53\x8b\xaf\xba\xa4\xca\x97\x3c\x41\xe1\xb0\xe2\xd0\xd4\x83\x85\x79\xdf\x8e\x3b\xb8\xe3\x38\x61\x50\x26\x58\x10\x47\x0e\x11\x26\xa8\xbb\x8f\xa8\xee\xe6\x78\x50\xbe\xbe\xb3\xa0\x7e\xec\x0f\x9e\xc3\xfd\xa3\x1e\x25\x45\x0a\x1c\x83\x05\xa6\xba\xcf\xc0\xc5\xbe\x10\xf7\xa1\x0d\xa3\x5f\x8d\x52\x7d\xac\xf8\x8d\xfd\x7b\x28\x6e\x65\xa8\xee\x7a\x73\x60\xe7\x70\x4c\x16\xa5\xf0\xaf\x50\x60\x4c\xfc\x1d\x4e\xf5\xec\x5e\x4e\x78\xee\xbb\xa7\x98\x98\xd7\x80\x48\x54\xf2\xcd\xf8\x05\xdd\xa8\x92\xc9\x4c\x78\xc7\xf9\x3a\x3e\x83\x3a\x17\xba\x12\xc3\x9b\x4b\x95\x49\x8b\xbc\xbd\x59\xdc\xe3\xcd\xe6\x8c\xbe\xc5\x2f\x57\x71\x9b\x03\xce\xf4\xc4\x1d\x6f\x21\x55\x71\x0b\x29\xf0\xad\xb1\xcc\x82\xbc\x46\x40\x99\x72\x64\x13\x48\x34\xc5\xa3\x4d\xb5\x90\xd7\x90\x43\x70\x4b\x17\xcc\x65\x97\x07\x49\x58\xd2\x0b\x3f\xf3\x11\x94\x68\xde\x07\x0f\x33\xa0\xc0\x88\xec\xb2\x0a\x8a\xcd\xf1\xf3\x21\x23\x50\xcd\x9a\xf7\x26\x28\xef\x1d\x90\x44\xe4\xef\x79\x16\xc0\xd4\x80\x16\x65\xc9\xd8\x35\x2d\x2c\xf8\xdd\xef\xe4\x1c\x86\x32\x94\x3e\x1b\x40\x13\xb0\xb3\x56\xf6\xea\xfb\x4c\x69\x19\x49\x4d\x0e\xdf\x3f\x60\x45\x91\x72\x6c\x0f\x39\x0c\x04\x7b\x6d\xa3\x24\xc0\x4c\x29\x5c\xdb\xe0\x7e\x0e\x33\x9b\x13\x73\x55\x87\x4e\xdc\x8f\x10\xe1\x3f\xc6\xa8\xd6\x91\x66\x46\x3f\x40\xbb\x28\x3f\x61\x98\x21\x38\xab\xea\x51\x45\x8c\xfc\x87\x6b\x22\xeb\xbf\xad\xce\x39\xb5\x7f\xd5\x39\xa1\xff\xd4\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\x8d\xbb\x6b\xfb\x2f\xcb\x21\x5b\xf3\xaf\x1c\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\xac\x79\x58\xe7\x7f\x99\xe6\x61\x3a\xfe\xd2\x3c\xd0\x87\xf5\x47\xbe\x1a\xc7\xf6\x0a\x71\x4c\x10\x4d\x6a\xce\x41\xd8\xc3\x32\xa6\xe9\x8b\xc0\xa0\xb5\x12\x55\x2b\x3c\x91\x6d\x3a\xd8\xd8\x42\x4f\x0b\xd0\xa8\xd4\x04\xdf\xa3\x90\xac\x43\xe8\xfd\x38\x47\xa8\x70\x90\xa3\xfd\xa2\xc7\x94\x60\x7e\xa0\x53\xc4\xea\xe1\xef\x99\xe1\x09\x5a\x94\xd4\x9f\x95\x37\xa5\xc0\xaa\x02\x10\x18\xfe\x70\x79\x9f\xa0\x3c\x69\x10\xba\xd6\xa5\xf5\x89\x14\x35\x62\x13\xc9\xc3\x15\x86\x9a\x0b\xad\xf5\xe9\xe8\xaa\xb1\x64\x5b\x7f\xc7\x09\xdc\xe8\x46\xe1\x31\x59\xd3\xce\xb3\x57\x3c\xb8\x4e\xa9\x91\xee\x8f\x49\xd7\x73\x81\xab\xe6\x0d\x31\x9c\x24\x5d\xc4\x61\x7b\xd7\x7b\x09\xbc\x26\x2c\x51\x8a\x27\x94\x25\xcb\x56\xae\xad\x67\x71\x63\x2c\x74\xa0\x59\x33\x8f\x18\xa7\xda\x3b\x92\x0c\x4e\x78\x62\x3b\x01\x5b\x6e\xc6\x6e\x86\x5a\x50\x1c\xcf\x76\x8a\xdb\xb6\xa1\x41\xe7\x71\x52\x86\x5b\xc2\x14\x32\x65\xa0\x66\xe3\x41\x87\xe3\xec\x62\x51\x97\x9a\x2c\xe4\xd7\xf8\x23\xa2\x37\x73\xc1\x90\x38\x6d\xcd\x7e\x49\x16\xe3\x7d\x72\x0c\x36\xcc\x08\xba\xd5\x18\x55\xc4\xb0\xf9\x40\x3b\xc2\x5a\x4b\x91\x79\x06\x71\x76\x31\xf3\xc1\x32\x9f\xb8\xca\x29\x3d\x89\x2b\x90\xa1\x19\x55\x37\x23\xee\x69\xca\x36\x55\xb3\x86\x57\x68\x3e\x6d\xe8\x4d\x19\x84\xf7\x70\xbd\xa1\xdc\x7c\x4f\x74\x0e\x49\xd1\xbd\xbc\x29\x28\x3d\xec\x0c\xe0\x28\xa0\xd7\xae\xcf\xe1\x53\x5e\x4b\x45\x71\x7a\xa0\x13\x17\xaa\x9c\x92\x45\xb4\x89\xcd\xd7\x3b\x5e\x0c\x94\x5f\x4a\xd8\x1b\x78\x60\x2f\x56\x21\x5b\x39\x05\xe7\xcb\x75\x57\x5b\x45\x2d\xfa\xac\x77\xd2\xac\x29\x7a\x05\xc0\x17\xbd\xc2\xc2\xa1\x72\xe6\xb7\x4b\x9b\x52\x91\x91\x98\x60\x55\xb2\xf4\x36\x47\xaf\x7f\x4d\xd3\xdf\x10\xe3\xdc\x36\x00\x4a\x55\xc3\x29\xf2\xba\x9a\x8b\xc8\x34\x82\x61\xc1\x6e\xaa\x2d\x24\xeb\x34\x6e\x87\xbe\x26\x84\x17\xf3\x5d\x32\x10\xeb\x18\x4c\x23\xa2\x1c\xb1\xce\xf9\x69\x36\x34\x62\xd0\x8c\xe8\xc3\x65\xe7\x71\x2d\x31\xe4\x80\x28\x5d\x0b\x62\x3c\x33\xcb\xd2\x4b\x91\x3e\x2b\x66\xcc\x3b\x5c\x94\x15\x02\xa3\x2c\x05\x57\xe4\x73\x33\xc5\x88\xf5\x43\x96\x41\x4a\xe0\xf5\x41\xa9\xab\xf7\xa0\x43\x42\x4f\x84\xde\xc5\xfc\xb8\x83\x1c\x29\xb8\x1b\x4e\x42\xfa\x69\x73\x22\x04\x14\x1d\xaa\xa3\xa7\xba\x93\x0b\xf1\xd9\x03\xd4\x0a\xbd\x9f\xc9\xe3\x2d\x98\x3c\x46\xca\x4d\x18\xa8\xc8\x8e\x33\x4f\x27\x6d\x17\x67\xf9\x6b\xed\x56\xa5\x6c\x12\xe9\x7f\x7c\xa5\x24\x0b\x21\xf0\xd2\x0a\xa4\x76\x8e\x0c\x9a\xb6\xc9\x54\x0b\x4c\xc3\xd3\x29\x38\xc8\xc3\x20\x4c\xab\x68\x7e\x27\xf6\x65\x47\xf1\x86\xec\xc3\xd0\xa9\xe1\x53\xed\xdb\x01\xc5\x5f\xd3\xae\x9a\x41\xcd\x6e\x18\x22\xfa\x85\x6c\x74\xa5\x2b\x97\x57\x33\x8c\xc1\x64\x59\x31\x8f\x63\x21\xb2\x53\xf2\xcf\xc6\xf4\xf5\x5f\x96\x4b\x0f\xed\xdf\x3f\x0f\xf8\x9f\x98\x6e\xfb\x06\xf9\x7a\xe9\x3a\x7d\x3e\xcd\x9b\xd9\x14\x31\x87\x58\x7b\x1d\xd7\x35\x3f\x80\x79\x44\xfa\xd3\x8e\x0b\x6c\xaf\x1a\x64\x86\x0e\x10\x85\x8e\x58\x2e\x4c\x39\x22\xd9\x96\xba\xbb\x63\x03\x6d\x09\xb6\xcd\x0f\x54\x65\x9a\x5c\xd4\x20\x8d\x0f\x3d\xa0\xc1\xac\xe0\x09\xd3\x95\xbb\x00\x08\x1c\xa7\xf1\x6f\x7c\xc6\x5e\x50\xbf\xd2\xc5\xcf\x1a\x9f\xf5\x69\xbf\xd2\x87\x68\xbc\xeb\x28\xe9\x88\xce\xfb\x56\x24\xfb\x06\x2f\x65\x7a\x76\x0b\xf0\xde\xa8\x24\xce\x7c\x4f\x5d\x8f\x1c\x7a\x86\xf1\x21\x95\x74\xd1\x02\xe1\x83\x3f\x15\xe1\x83\x80\xa0\x41\x94\xbc\xc4\xe4\xc7\x3f\x55\xa3\xd2\x01\x34\x72\x00\xb3\x28\x4a\x28\x35\x34\xa7\x03\x97\x62\xe5\x36\x46\x69\xbc\x33\x93\x0f\xb4\x47\x5d\x38\xab\xbf\x59\xe0\x1b\x52\x93\x06\xa0\x03\x99\x02\xeb\x02\x03\x74\x49\x76\x9f\x7e\x9e\xf7\x1c\xb1\x51\x67\x68\x4c\x56\x23\x05\x68\x7d\x8d\x6a\x75\xa0\x02\x9d\xab\x3a\x37\x76\x43\x7e\x41\xb1\xee\x1b\x49\x2e\x93\x26\xe8\x8f\x75\xc1\x70\xe4\x80\x58\xe0\x91\xec\xe5\xdb\xf4\x8d\x47\x08\x05\x5a\x93\x41\xfd\xc7\x74\xf6\x76\x94\x74\x66\x16\x30\xec\xe3\x14\x1d\x6e\x96\x38\xbd\x3b\xc3\xbc\x58\xb8\x23\xbe\x9c\x83\xb4\x93\xd9\x1f\x53\xf1\xa3\xbb\x31\x8d\xc4\xae\xf4\x50\xed\x44\xc1\xa2\x99\x5f\x2f\x33\xdd\xf5\x63\x7a\xf3\x63\x7f\x58\x8d\x5d\xb7\xd2\x94\x12\x8f\x25\x01\xc3\xed\x29\x27\x50\xcc\x91\x48\x91\x8f\xf7\xdc\x2e\x39\x37\x7e\x0b\x89\xfa\xd9\xe0\xda\xe3\xee\x9d\xf8\x0c\x9c\x43\x64\xe5\x4c\x75\x4a\xd9\xd0\xde\x94\x99\x81\x88\x63\x72\x47\x83\xd1\x18\xeb\x48\x98\x0e\x63\xa1\xa8\xa4\x19\xd0\xbd\x3b\x51\x3d\x0e\x2d\x7c\x6e\x52\x38\x85\x51\x3e\xee\x1d\x3f\x38\xef\xf6\xdc\x75\xd6\xa0\xb8\xb7\x15\xc3\x91\x09\x91\x1f\xf8\x72\x62\x3e\x58\x27\x05\x20\x87\xd0\x00\x7b\xc5\x98\xbe\x9e\x20\x47\x7e\x49\x23\xf6\x55\xe3\x25\x04\x1a\xbd\xde\x2e\xbf\xf1\xbd\x26\x72\x00\x41\x5d\x75\x42\x39\x63\x9d\x6a\xce\xfa\xcc\x8f\x1d\xba\x58\xeb\x32\x66\xf2\xbf\xe2\x72\xd5\x20\xa4\x05\xea\x67\x35\x1b\x7b\x6f\x63\x42\x31\xde\x0e\x32\x59\x99\xbb\x7a\x4e\x71\x5f\xe5\xf7\x21\x37\x6e\xf5\x41\x88\x25\x0b\x93\x87\x4e\xbe\x15\x97\x8b\x2e\x9b\x2c\xfa\x8f\xb8\x5c\xd0\xee\x3c\x61\xc4\xd9\x54\xcd\x58\x1e\x02\x5d\x64\x1e\xac\x74\xab\x1d\xa4\xde\xb5\x03\x80\x3c\xc1\x01\x24\xdd\x53\x84\xe0\x52\x27\x80\xe8\xf3\xac\x45\x80\xd5\x43\xb2\x65\x06\xb0\x06\xcc\xea\x12\xf3\x12\x35\x3c\x19\xf2\xba\xe2\x92\x03\x15\xd9\x39\xbc\xc5\x9f\x35\xe0\xad\x19\x46\x11\x32\xa5\x84\x27\xe0\x3a\xcb\x7f\xf2\x1d\xec\xba\x97\xff\x2e\x9b\xdf\xfe\xae\x85\x84\x0d\x01\x12\x92\x3a\x3f\x4a\x4d\x8b\xa4\x63\x51\x0e\x37\x6a\x54\x99\x59\x39\x56\x40\x14\x28\x39\x97\xce\xcb\xb2\x8a\x57\x2b\x4b\x6d\x31\x38\x31\x51\xbf\xf6\xbb\xa7\x70\x6f\xa3\x16\x06\xaa\xe2\x55\x89\x01\x84\x06\x4a\x7c\xdf\x75\x8d\x06\x42\x34\x4d\x5c\x16\x8e\xcd\xfd\x71\x50\x75\x8f\xac\x49\x1b\x38\x51\x8d\x8e\x17\xaa\x8b\x7c\x34\x9d\x71\x7c\x87\x49\x14\x3c\x25\x03\x82\xfc\x70\xbc\xd3\xfa\x53\xbf\x83\xa7\x91\x4e\xb3\xf0\xe5\xbc\x1c\xc9\xb1\xe5\xc2\xe1\x4d\x94\x82\xae\x91\xb7\x7f\x04\x5e\x97\x7a\x8f\x59\x19\x06\x77\xf4\x2e\x1e\xc0\x7b\x34\x26\xb9\x90\xf7\x22\x59\xbf\xad\xb9\xae\x55\x67\x33\x91\xba\xa2\x1e\x36\x03\xe6\x96\xfc\xd0\x74\x0d\x74\xaa\xf1\x2b\x00\xbf\x2c\x00\xe2\xd7\x73\x4e\x7f\x53\xc4\xf8\xa3\xdb\x67\x92\xf4\x61\xf1\xc8\x1f\x90\x3c\x57\x38\xff\x3e\xe9\x1b\x9b\xd8\xe6\xad\x2f\x48\x6d\x1f\x9b\x50\xfe\x00\xb5\x51\x39\x65\x7a\x09\xfa\x38\x11\xe4\x34\x05\x6f\xab\x91\x9c\xb4\xc3\xfc\xb4\x90\x14\xbc\xd5\x73\x40\xb4\x00\xc0\xf7\x2c\x4f\x2b\xf4\xa3\x30\x18\xa8\x54\x20\xc1\xfe\xad\x18\x20\x1f\x73\x2d\xe1\xfb\xd0\x05\x55\xc1\x4b\xb7\x23\x20\x46\xcf\xdc\x9d\x14\x8d\x62\x68\xf2\x1f\x70\x28\x2f\xb7\x0c\x6a\x6b\x6b\x89\x17\x93\x52\xf9\x21\x0a\x04\xb7\x96\x5a\xce\x09\xfd\x53\x41\x32\xb8\x6d\xc9\x17\xba\xad\x3f\xf2\x49\x3d\x6e\xcc\x48\x1e\x92\xf2\x40\x2c\xca\xd0\x16\x0f\x16\x2b\xb9\xed\x52\xb1\x56\x24\xee\xc0\x03\xa6\x7e\xa3\xd8\x14\xfc\x4d\x2c\xc0\x5b\x76\x51\xe8\xde\x16\x3b\x73\xab\x0e\x2d\x16\x63\x4c\xa6\xd0\xea\xa9\xd2\x78\xd5\xf2\xdc\x92\x17\x15\x82\xbb\xcc\xa0\x41\xf3\x0b\x3b\xcc\xbe\x52\x9a\x8e\xc9\x18\xb3\x85\xd9\x4a\x28\xad\x8a\x18\x17\xf7\x5c\x8e\x0c\x62\x1d\x52\x81\x19\xcc\x33\x8d\x08\xb9\x62\x8c\x72\x8e\x91\xa7\x64\xb4\x13\x66\x65\x97\x78\x8b\xfa\xb4\x1b\xab\x76\x97\xd6\xb4\x78\x56\xa2\x03\xdd\x64\x37\xa1\x96\x23\x9f\x6d\x1b\xb9\xe1\xb7\x62\x26\x98\x88\x20\x72\xa6\xcb\x1e\x9f\x3a\x03\x1b\x91\x88\x45\x17\x6c\x22\x0a\x57\xc7\x2a\x81\xeb\xc8\x64\x46\x1a\x26\x74\xf2\xdd\x1e\x44\x30\x92\xa6\x45\x26\x8d\x53\xb9\x61\xfc\xcd\x6d\x95\xbf\xc0\x9f\x79\xa4\x67\x44\xb6\xc1\x26\x29\x37\x69\x98\x9b\x17\x78\x88\x32\x99\xbb\x26\xac\x5e\x29\xdc\x07\x3e\x4a\x6d\xed\x94\xcc\xe0\xb0\xc2\x72\xe6\xa8\x69\xfe\x78\xb5\x66\x94\x8a\x3d\xdd\x5f\xf1\x4b\xf0\x47\x72\x10\x57\x54\x99\x7e\x84\x20\x85\xb2\xb9\x62\x50\x03\x8e\xa5\x37\x38\x70\xd9\x79\x40\xa9\x58\x50\x85\x73\xc0\xe0\x63\x92\xee\x94\xa9\x09\x62\x87\x43\xab\x45\x86\x6a\xbb\x97\x60\x4e\x56\xf1\x91\x65\xac\xd3\x94\xee\x19\x4c\x54\xfe\x42\x47\xb3\xd1\xce\x71\x41\x5c\xe2\x35\xe3\x4c\x26\x01\x6d\x81\xfa\x41\x0d\x79\x6b\xe1\xdd\xc8\xea\xef\x90\xf5\xb3\xe3\x1a\x48\x64\x06\xe8\x14\x4b\x7d\x2b\x56\x29\xc1\x1d\x21\xce\x7d\x0e\xec\xc9\x49\xc9\xc2\xbe\x80\x29\xfe\x39\xeb\xe0\x60\x55\xf0\x2a\x9a\x66\x07\xd0\xae\x0f\x3f\x10\xf2\x12\x86\xdd\x55\xd9\x0e\x8e\x13\xb4\x92\xfb\x1f\xce\x49\xfe\x6d\x5f\x23\x0e\xff\x72\x3d\xc3\x71\x09\xd3\x1f\x74\xc3\xfe\xfc\x40\x9c\x1a\x55\x43\x82\x2d\x76\x44\x09\x5d\x19\xc2\x62\xf5\x9f\xf3\x64\x93\x5a\x64\xc9\x7d\x9e\x28\xbf\x42\x23\xdd\xc5\xfa\x15\x1e\xee\xc9\xaf\xcd\x81\xaa\x4a\x92\xf9\xa1\x97\x3d\x87\x2b\xef\xea\x86\x3c\x82\xca\xca\x4d\x3c\x75\x75\x95\x1b\xad\xc0\xc5\x9f\x96\x4e\x15\x50\x55\x7f\x50\x0e\x98\x68\x11\x00\xe1\x66\xa4\xc8\x91\xf0\x7e\xe5\x11\x46\x40\xf0\xb2\x11\xf0\xb3\x9c\x4c\xc4\x4e\x9e\x94\x22\x93\xa0\x2b\x50\x5f\x9a\xda\x9c\xc8\x21\xd8\x6d\x56\xcc\xe2\xe4\x96\x8d\x4a\x83\xac\x71\x75\x04\x95\x59\x65\xd5\x3f\xdf\xe1\xd3\x68\xaa\x14\x68\xca\x82\x72\xdd\x00\x03\xb3\xf9\x61\x17\x8a\xf0\x3d\x5c\xdf\x9e\xe3\x1e\x74\xe9\xed\xf5\x94\x16\x46\x06\xfd\x94\x8b\xb6\xf8\x6c\x4b\x7e\x76\xf8\x9c\xf6\xac\xc3\xdc\x09\x67\x42\xae\x9e\x64\x7d\x29\x69\xa0\x2c\x58\xbe\x55\x61\xe2\x7e\xc5\x7b\x81\x54\x81\x7a\x76\xb2\xde\x02\x77\x80\xe5\x74\x62\x96\x89\x0a\x25\xe6\xbf\x93\x02\xb4\x4e\x01\xa7\xdb\x22\x00\x22\x70\x3a\x3a\xbf\xcf\xf2\x78\x0f\x9a\xb1\x17\xaa\xdf\x8c\x58\xa5\x5a\x1d\x5d\x3f\xa9\x5e\xd9\x66\x2b\x3d\x44\xea\xb8\xae\xb8\xc9\x58\xd8\xa7\x99\xe4\x5d\x50\x42\x14\x4e\xa1\xea\xeb\x2f\x83\xd2\xe6\x54\xa2\xaa\xd9\xf8\xee\x26\xc7\x84\x65\xd3\x90\x78\x3a\x69\xa0\x79\x87\xd7\x3f\x0d\xcf\x85\x57\xc4\xe4\x8e\x0e\x75\x63\x5f\x12\x85\x54\x09\x61\xc7\xed\xbe\x92\xfb\xd9\x1a\xf1\x33\xdf\xe4\x2c\x53\x25\x56\x18\xbe\xfc\x59\x47\x87\xd1\x94\x86\x9f\x58\xb9\x1a\x78\xbf\x51\x80\x4d\xd3\x36\x4d\xbf\x4c\x66\x6d\x26\xa1\x79\xb7\x53\xdf\x61\x6e\x11\x67\x24\xc1\x0a\xa5\xd2\xd5\x75\xe8\x17\x4e\x1f\xa2\x39\xf0\x14\x11\x55\x1f\xc5\x53\x82\x9d\xeb\x99\xe5\x69\x23\x53\xd5\x59\x45\xdd\xd1\xa4\x8a\x7b\x10\xa2\x96\x24\x1d\x2c\x2d\x21\x70\x79\x1c\x05\x30\x1f\x8c\x29\xc1\x21\x2c\x09\x4a\x0c\x92\x83\x0d\x51\x3d\xef\x8d\x88\x2e\xb4\x27\xbd\x8b\x05\x30\x35\x12\x87\x0b\x80\x36\xd6\xd0\x16\x3e\x96\xad\x34\x4d\x68\x17\xac\xfc\xd5\x8e\xed\xe0\x1d\x62\x88\xf9\xbb\xc8\x4a\xde\x43\x7c\xf6\xf7\xae\xd8\x1c\x23\xf2\x13\xf7\xbb\xaa\x11\x39\x3f\xa7\x0a\x93\x56\x13\xe1\xaf\x78\x62\x18\x53\x57\xcc\xb8\xc5\x61\xe3\x77\x98\xd1\x71\xb1\x74\xd1\x00\xad\xc3\xb0\x47\xd4\x6b\x3a\xd2\xcb\xa0\x8f\x4a\x0d\x5b\x24\x7c\x2c\x08\xc4\x54\xf0\x06\xe1\x8d\x99\xca\x48\x46\x34\x74\x97\xce\x72\x38\x96\x36\x73\x97\x66\xbc\xec\x29\xd8\xcf\xf4\xb6\x99\x04\x0f\xf8\x6a\x06\x49\xb5\xef\x34\xae\x6b\xaf\xe2\xfa\x01\xe9\x82\xe8\xa3\x81\xd9\xf3\x1d\x93\xaa\x88\xaa\xa6\x04\x89\xe1\xc6\xa0\x03\xb7\xa5\xb3\x0a\xf4\x1f\x76\x03\xdb\xbf\x2c\xeb\x98\xff\xe6\x06\xa8\xe3\x84\x20\x26\xb0\x03\x7c\x5f\x31\xd8\x1c\x3e\xf7\x59\x6b\x2f\xdd\x3a\x28\x54\x14\x67\x13\x04\x35\x48\x93\x58\xe0\xae\xfc\xe6\xa2\x27\xd9\x4f\x96\x07\x18\x36\x10\x7f\xfc\x8f\x9b\x23\xd6\x11\xd4\x52\x89\xba\x86\xf5\x7e\xc4\xba\xb9\x2a\x5c\xe5\xed\xf3\x13\x68\x83\xcc\xd2\xc9\xfb\x39\xd8\x82\x43\x78\x2d\x1b\x73\x6c\xdb\x76\x54\x4a\x5d\xa6\x28\xc9\xef\xa1\x68\x49\x5b\x4d\xbe\x7c\xa6\x78\x08\xd0\x4c\x58\xb8\xdd\x07\x3e\x2a\x82\xbd\x09\x81\x81\x9e\x5b\xd5\xe2\x70\xfc\x2b\xab\x7e\x3d\xe0\xc7\x64\x94\xcf\x2a\x00\x15\x6b\x7d\xc6\xd4\xe4\x1c\x33\x25\x35\x2a\xc6\xa4\x87\x22\x26\x88\xfc\xa1\xf5\xc2\x87\x6e\xd1\xbc\x07\x50\xb8\x72\xe1\x41\x0a\xe3\xb6\x00\x0f\x52\x12\x64\xaf\x53\xd8\x91\xfb\x54\x42\xa5\xbe\x03\x8c\xd2\xdf\x7e\x28\x74\x8c\x29\x24\x89\x73\x73\xf2\x28\xa4\xaf\xda\x28\x8e\x56\x2f\x31\x85\x35\xf4\x69\xa7\x50\x21\xa7\x58\x12\x4d\x02\x3d\x9f\x67\x1d\x40\x37\xc3\x72\x9e\xa7\x4c\xc6\x1e\x09\xcd\xe6\x9d\xcb\xc6\x80\x28\x0d\xee\x77\x2a\xfa\x91\xfe\x92\x97\xb3\x90\x25\x3f\xd7\xf6\x15\x45\x4e\x46\x49\xa7\x15\xa2\x4a\xa2\xab\xf1\xf4\x7e\xfc\x27\x21\x20\xd7\xa6\xe8\x7a\xe7\x72\xe9\x20\x04\xc9\x6a\xea\x92\x9c\x3d\xe9\x89\x88\xe1\xb4\x9d\x48\xe9\x27\xaf\x81\x52\x0d\xf1\x9a\xcf\x6a\x8a\xf9\xc1\x4a\xee\xe7\x82\xf1\x05\x30\x63\xf2\x11\xa9\x33\xb5\xa0\x38\x9a\xd2\xb0\x3b\x2b\x8e\xcc\x43\xe8\x89\xf5\x11\x06\x53\x5c\x0b\xcf\x1d\x4c\x28\x49\xb6\x36\x32\x9d\x72\x82\x22\x8e\x8b\x28\x2a\xf2\x0c\x11\xd1\xa8\x60\x31\x96\x91\x19\xd6\x48\xe6\x9d\x66\xdf\xee\xc1\x53\xe2\x52\x1d\x3d\xbe\x27\x76\xed\xf3\xc7\xd3\x8f\x70\x8d\x06\xf9\x82\xf7\x83\xd3\x55\x0e\xc6\x70\x5e\xc0\x23\x9d\x80\xc5\xfc\xca\x94\x79\xd0\x45\x34\x4f\x06\x7b\x67\xd2\x91\x39\xa4\xcd\x93\xf5\x77\x5e\x42\xba\xf4\x1d\xe8\x50\x31\xaa\x1d\x14\xb0\x89\x7b\x61\x25\x98\x3e\xc4\x2c\x08\xab\x85\x84\xf3\xdd\x63\x5a\xb9\xac\xa7\x31\x49\x5b\xa1\x59\x22\x17\x69\x34\x93\x23\x2c\xd4\xfd\x6b\xbf\x6b\xa1\xd1\xba\x23\x65\xd4\xc6\x5d\x11\xdd\xd3\x80\x71\x65\xd9\xee\x58\x72\xe6\xb6\x52\x54\xb6\xbb\xa9\xbb\x54\x7b\x2f\x65\x12\xd5\x04\x8b\x1d\x49\xcf\xf7\x9e\xb5\x5c\xee\xb6\xa1\xc8\xcf\x4b\x36\x70\x7c\x8f\x1b\x63\x48\x72\x81\x43\x44\x70\x3b\xe6\xf8\x12\x7c\x18\x82\xdf\x6f\x97\x01\xd4\x11\x11\x2d\xa1\x48\xe6\xe7\x1f\xce\xe9\x10\x33\x53\x63\x0f\x21\x72\x21\xcc\x43\x10\x0c\x5c\x49\xf5\xdb\x59\x03\xb9\x18\xec\x85\xdd\x09\xe1\x49\xd0\xcd\x0a\xd0\x4f\x95\x1b\x2b\x41\xc2\xf8\x15\x12\x63\xd7\x74\x7b\x98\xd0\xd4\xa9\x2d\xa9\xbf\xe7\xf2\x5e\x3f\xea\xe7\x54\x36\xdd\x85\x6a\xf1\xf3\xb4\x46\x05\xfc\x9f\x58\xbc\x49\x95\xc7\xbe\x0d\xba\x62\xc3\x88\xce\x92\x4f\x8a\xc5\x3e\xf9\xfe\x4f\x66\x2c\xbf\xec\xf7\x2f\xf3\x17\xeb\xdf\x69\xc3\x7f\x75\x6f\x11\x94\xd5\xbc\x63\x1a\x77\x50\x9b\x32\x9c\x13\xc0\xba\xa0\x69\x9c\x51\x64\x07\xd9\xfb\xee\xec\xec\xf1\xb3\x3b\xc7\x85\x09\x20\x66\x90\x98\x0d\x77\xbf\x2e\xc8\x4c\xee\x86\xc5\xe6\x59\x7b\x4e\x75\x34\x8d\x09\x08\x08\x98\xa8\x49\x9d\x7f\x93\x37\x8e\x58\xcc\xf9\x05\x05\xd0\x38\xfd\x7d\x68\x45\x51\x92\x55\x14\x54\xb6\xd1\xd5\xc5\xb5\x96\x3c\x82\xe3\x65\x2c\x67\x7e\x45\x31\xf8\x61\x00\x7b\xfb\x63\x7e\xdd\x64\x1e\x97\x0d\x95\x93\x2d\xa1\x0b\x70\x23\x45\x80\x45\x51\x9c\x6b\x1c\x58\xec\x8f\x2e\x01\xfe\x92\xa7\xa8\xf0\xf8\x42\xfb\x51\x96\x61\xba\xb6\x07\xf6\x04\x9a\xe8\xc5\xa7\xb1\x10\x73\x34\x9a\xc1\x73\xaa\x34\x4b\x30\x54\x11\xe7\xc8\x87\x13\xf3\x83\xa1\x4b\x37\xee\xc5\x25\xd1\xa4\xce\x77\x99\xd1\x96\x82\x10\xce\xb4\x80\xb6\xd0\xf0\x36\x1d\x12\x63\x28\xde\x61\x94\xf4\xd9\x98\x93\x69\x59\x5b\x31\xc4\x64\x75\x42\x26\x64\x31\xce\xf6\xd2\x5e\xf8\x2e\xf8\xae\x64\xfc\xc8\x79\xc7\x04\x54\x07\x61\xf2\x13\xa3\xa8\x69\xfe\x94\x9c\x61\x18\x74\x01\x43\x0d\xb1\x6f\x5e\x5d\xc8\x1f\x2e\xbe\x64\xea\x9e\x57\x87\xd9\xa2\x47\x00\x9b\x12\x97\x61\xc2\x53\x6a\x43\xb0\x41\x71\x5a\x3c\xc5\x2e\x9f\xa7\x8f\x6e\xf4\x76\x45\x13\x6a\x83\x6f\x38\xd1\x1d\x8c\xa2\x08\x59\x4b\x85\x8b\x8a\x3d\xe0\x24\xcb\x93\x12\xe4\x75\xef\xfd\xf6\x3c\x95\x73\xfc\x2b\xef\xd6\x50\x55\x95\x8b\x7a\xc1\x23\x0c\xae\x35\x05\x04\x5b\x3b\x89\xa8\x1a\x72\xdd\x46\x71\x48\x55\xf5\x10\xfc\x72\x18\x0d\x6d\xc3\xdf\x7f\x85\xef\x78\xdf\x93\x82\xc0\x0c\x49\x21\x43\x08\x52\xee\x49\x65\x23\xd1\xd7\x02\xe3\x75\x83\xcc\x62\x93\x5b\xd4\x40\x42\x9e\x5b\x96\xc0\x94\xb5\xbc\x4f\xc1\x57\xf0\xf8\xa9\x3b\xaa\xac\x6b\xec\xfd\x46\xd1\x1c\x24\xc4\xdc\xe5\xd5\xa4\xaf\xb0\x29\x8c\x12\x49\x1a\xa8\x42\x27\x90\x7a\xa3\x22\xa5\x09\xc1\x6c\x7a\x0a\x50\x39\x28\xed\x23\x90\x5a\xe1\xf8\x1a\xec\x04\x3d\x50\xdc\x8c\xf0\xfe\xec\x14\x50\xde\xf2\x73\x97\x37\x6b\x81\x49\x7f\x91\x6e\xcf\x23\xf6\xae\x04\x4f\x15\x66\x96\xde\x00\xd8\x35\xe8\x20\xa7\x25\xc7\x8a\x06\x86\x6d\x28\xb9\x77\x7f\x48\x49\x27\x2d\xd4\xfa\x23\x3b\xba\x7b\x3d\x03\x3c\x76\x35\x10\x7b\x05\x1c\xfd\x4b\x37\x81\x0b\xd4\x73\x20\xfd\xef\x07\x7f\x59\xcb\x25\x23\x4b\xc8\x2a\xe3\x0a\xf6\x5d\xe7\xb9\xc1\x7e\x3a\xfb\xed\x79\xa0\x85\x0a\xb4\xb1\x8d\x33\x14\x80\xf7\x34\x51\x90\x64\x0a\xb3\x59\xab\x76\x6b\xb1\x4a\xe4\x8d\x34\x66\x19\x1f\x82\xc9\x25\x67\xa2\xf9\x3b\xf8\x5d\xf3\xeb\xd0\xfb\xa9\xd5\xa6\x34\x60\xee\x9a\x77\x5f\x8c\xa2\xc2\xe8\x95\x8d\xee\xd9\x9b\xb7\x27\xe5\x71\x58\xc8\xca\xf7\xdc\xb2\x71\xac\x68\x4b\x91\xb8\x31\x4f\x3b\x1f\xdb\x61\x71\x53\xb4\xd3\x50\xd2\x80\x0e\x70\x3e\xc3\x18\xdb\xfd\x02\xe9\x37\x9e\x6c\xf3\x8f\x56\x37\x7f\xf9\xbf\xcb\x6d\x74\xff\xff\x42\xc7\x26\xfc\x27\xdb\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\x39\x1f\xff\x32\x81\x52\x85\xff\x65\xcf\x10\x6c\xff\xa7\x70\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\xd5\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\xea\xf7\x57\x5d\x43\xb1\x85\x22\x01\x36\xac\xc9\xbc\x72\x0f\x6f\xff\xbc\x1f\xc7\xf2\xf8\x4f\xc5\x31\xc3\xdf\x60\x25\xb3\x6d\x82\x1c\x63\xc9\xb1\x5d\x1a\x95\x6b\xde\x43\x1d\x49\x9e\xa0\xd2\xb1\x6b\xca\x43\x5d\xf8\x85\xa6\x21\xc0\xb7\x83\x84\x4b\x16\xb4\x44\x31\x85\x7e\x35\xe0\x41\x82\xae\xbf\xe4\x1b\x07\xa5\xa7\x00\x85\x7f\x30\x6b\x6e\x8f\x42\x82\xc7\x52\x12\x9a\x4a\x82\xf7\x7c\x36\x88\x8a\x87\xba\x24\x72\xaf\x64\x0a\x88\x3f\xfe\xce\xa3\x10\x4a\x3c\xaa\x53\xe4\x86\xa8\x24\xf8\x2e\xa5\x9d\x56\x06\x71\xc8\x11\x75\x54\xc4\xd6\x0c\x38\x96\xcf\x51\x75\x54\xf8\xe0\x34\x5e\xb8\x37\x78\xe1\x51\xf8\x04\xd1\x7b\x01\x32\xfd\x04\x31\xbc\xbb\x31\x7a\xe6\x31\x3a\xea\xfe\xe3\x32\x3b\xe8\x31\xf9\x05\x36\xfb\xe5\x35\x5f\xa6\x51\xb8\xff\xba\x7a\xac\xb1\x65\x75\x48\xfb\xd5\x73\x85\xe4\xbf\xc7\x53\x4c\xee\x64\x7b\xea\x52\xca\xee\x6d\x75\xd4\x55\xa2\x25\xaa\xcf\xc5\xa7\x4f\xf4\x9b\xbe\xd4\x63\xf9\x03\xae\x7f\xcc\xab\x7f\xca\xab\xc7\xea\x90\x76\xf0\x57\x45\x38\x94\xc4\xcd\x91\xcf\x46\xff\x37\x5c\x21\x8d\xcd\x3f\x02\xd9\x5d\x4a\xe3\x95\x77\xec\x9b\x4a\x09\x91\x44\xea\x55\xc6\x0e\xad\x74\xca\x5f\x73\x20\xc1\xf7\xdf\x9f\x99\xcf\xc6\xf9\x5f\x73\x72\x26\x08\x7d\xe8\x68\xdb\x16\x1c\xf5\xe8\x3d\x73\x29\x1d\x8b\xe5\xd1\x73\x16\xdf\x8a\xe5\x31\x6b\xfa\x3e\xd4\x65\xb2\x0b\x15\xfc\x72\xe9\x08\xfe\xe9\xd3\x9f\x73\xa5\xff\x67\x3d\x69\x2c\x89\x99\xcb\xf0\xb0\x5b\x47\xe0\x43\x7f\xff\x7a\x66\x81\xba\x5e\x1a\x25\xb4\x32\xb5\x50\x29\x33\x84\xfe\xd2\x67\xf1\xfe\xf7\xfa\xf7\x39\x02\x5d\x95\x24\xde\xfa\x27\x9c\x06\x47\x7f\xa1\x3c\xde\xa9\x47\x7b\x69\x6c\x5e\x65\xac\xf6\x7f\xec\xa5\xb4\x33\x3a\x45\x6e\x8f\x82\x5f\xf9\x62\x0a\xdb\x52\xa2\xdf\x50\xa2\xaf\x9c\x87\x3a\xe7\xcf\xf1\x37\x81\xd4\x5e\xa5\x44\x7f\x99\x44\xdf\x8a\x60\xfa\x66\xc7\x2c\x21\x32\x9e\xa9\x44\xa3\xc5\x3b\xfc\xf9\x7b\x01\x36\xad\x61\x3c\x0b\xd4\x6d\xf3\xc9\x1c\xbd\xc0\xa1\x95\x3f\xf6\x0a\x87\xaf\x59\xe4\x10\x06\x6f\xf2\x86\xcf\xb2\x06\xa4\x4a\x86\x2f\xe0\x86\x2f\x8a\x86\xdf\xa0\x26\x64\x8a\x96\xaf\xbc\x86\xef\x20\xce\xd7\xb2\xe6\xe0\xfc\x0d\xcf\xbd\x12\x34\x3c\xd2\x08\x87\xfe\x86\x37\xfc\xaf\x78\xe6\xff\x88\x67\x77\x0c\xf5\xc7\xfa\xf8\x01\x44\xb8\x52\xf8\x66\x71\x3a\xa6\x42\xfa\xe6\x08\xd4\xfc\xd7\x1c\x12\x59\x84\x7f\xa5\x24\x9e\x09\x12\xaa\x2e\x0f\x75\x7f\xdc\xaf\x4f\xe3\x9a\xf2\xcb\x6d\x40\xc6\x63\x08\xc2\x67\x05\xc9\x63\xf8\xc3\x63\x04\xc1\x63\xf1\x05\xea\x40\x01\x6e\xf4\xca\x63\xf2\x29\x6f\x09\x02\xe2\x72\xca\x7f\xe3\xa5\x12\xdd\x97\x11\x3c\xe6\xb3\xfb\x37\x3c\xf7\x7f\xc1\x73\xfe\x67\xbc\xeb\x8f\xb1\xeb\xe8\xff\xc5\x5e\xfc\x63\x8f\x72\xf4\x7f\xf6\x63\x30\xb8\xd2\x9f\xf7\xfd\x69\x6f\xff\xb1\x3f\x1f\x6b\x6c\x9e\xc6\x0a\x49\xec\x33\x24\x84\x14\x29\x3c\xff\xb0\xf3\xa2\x53\x40\x7b\x21\x91\x38\x28\x18\x86\x51\x0b\x2f\x70\xd9\x50\xee\xb3\x56\x54\x4b\xff\x31\x59\x91\x87\xf3\x77\x28\xc0\xe3\xb8\xca\xe3\x38\x22\xa9\x51\xa0\x3c\xf9\x05\x0d\x9f\x2e\x66\xb2\xb9\x2a\x04\x63\x83\xe1\xc6\xf2\x75\xb3\x60\xeb\xf8\x32\x78\x8b\xad\xe1\x0a\x6a\x2d\xb2\xce\xc3\xf6\xad\xe1\x2a\xa2\xe0\x78\x1c\x33\x3a\x8f\x96\x48\x4d\xd3\x05\x68\x85\xca\xf9\x5c\xc7\x48\x2e\x1e\xb0\x10\xd0\x03\x3d\xd1\x53\x3e\x7e\xf8\x8a\x7d\xe3\x27\x9a\xc2\x93\x4c\xeb\x59\x81\xfd\xe4\x7b\xe9\x8d\xdb\x29\x33\xc2\x06\x73\xf3\x3e\x54\x90\x16\x89\xdc\x97\x5d\x9e\x65\x65\x66\x83\x6d\x1e\x56\x0a\x1d\xbb\x41\x16\xd7\x57\x5a\x05\xfe\x9a\xb8\xce\x33\xbb\x2f\xba\x8c\x3a\xec\xe0\xc0\x21\xf6\x23\xba\x61\x85\xd2\x5e\x47\xd4\x58\xfe\x56\x1f\x81\x08\x2b\x23\xc8\x60\x63\x9a\x30\x25\xe2\xa8\xdb\x81\x56\xf1\xd4\xa4\x75\x94\xba\xb1\x6a\x3e\x86\xec\x60\x6a\x37\x70\xa1\x78\xea\x0a\xda\xd0\xd1\x40\x3e\xfb\xe9\xdc\xa2\x51\x3c\x59\xc9\x2d\xe6\x0e\xba\xae\x62\x05\xf7\xc1\x08\xd3\x1b\xf1\xdd\x54\x1f\xf5\xb6\xdb\x11\x2e\xa8\x99\x6f\xae\x36\x16\x4f\xe1\xe9\x30\xd1\xa4\xb7\x8a\xb8\x2f\xa5\x85\x05\x35\xa4\x16\x24\x97\xbe\x36\x06\xee\x0c\x50\x12\x61\xf3\x88\x97\xb6\xba\xe1\xf4\x34\x11\x31\x9d\xc1\xb4\x88\x1b\x8b\x89\xa6\x90\xd4\x58\xa8\xc5\x43\x47\x09\xcb\xbd\x85\xc2\xcd\xab\x99\x2f\x7d\x10\xad\x3c\x9e\x40\x1c\x96\xb6\x08\x0f\xdd\x44\x1b\x15\x24\x74\x3a\x29\x07\x28\x51\xed\xa4\xbf\x58\x84\x94\x5d\xbe\x12\x60\xaa\xd8\x12\xa2\xda\x8c\x69\x97\xd0\x30\x1c\x51\xd5\x22\x91\xb4\xcd\xd4\x00\x86\xb1\x75\xdf\xa5\x91\xda\x7c\x7b\x2c\x25\x66\x0c\xeb\x10\x6e\x89\xd9\xf8\x2d\x2c\x9a\x3c\x1c\x06\x01\xc0\x83\x5d\x60\xa2\xec\xaa\xa1\xec\x43\x0e\x28\xdd\x2e\x0d\xd9\xb2\xbc\x25\x94\x00\xed\x97\xee\xe3\x6f\xbf\xb9\xab\x1e\xd6\xcb\xb0\x56\xe3\xa1\xcc\x35\x6a\x3a\x10\x67\xc8\x5e\x8b\xa6\x19\x08\x84\x8e\x9f\x83\x11\x0a\x3c\x86\x45\x0c\x04\xae\xd0\xce\xbb\x8d\x62\xaf\xbe\xc2\x0c\x0f\x3f\x5d\xce\x1a\xe7\x7c\xac\x5f\x40\x4d\xea\xdb\xa1\x7e\x01\x5b\x18\x30\xd2\x01\x44\xcc\xe4\x43\x39\x20\x65\xcb\x1f\xcc\xff\x7e\x8c\x7e\x50\xc7\xf8\x83\xb8\xdf\x90\xab\x86\xec\x2f\x2b\xed\x0d\xf8\xae\x67\x70\x43\xe9\x00\xe3\xaa\xe5\xec\xb5\x1a\x37\x26\xe8\x71\xce\x26\x41\x1f\x78\x27\xe9\x89\x3f\x72\x47\x36\xf4\x62\x42\x36\x8f\xc9\xb0\xa5\x89\xb2\x28\xc9\x66\xdb\xb6\x24\x3e\xb5\xbe\x31\xd4\xcd\x98\xe5\xe6\xee\xa0\x30\x18\x91\x8c\xbc\x9b\x07\x7e\xce\xa6\x88\x9a\x83\xf6\x8d\x6d\x9d\x26\xce\xd9\x5a\xac\xf6\x42\xaf\x65\xfe\x6b\x28\xbe\x67\x2c\x76\x17\x1b\x41\x57\xa7\x5d\xda\xc9\x2a\x1a\x86\x02\xcf\x4f\xf0\x61\x1b\x46\x1e\x22\x8e\x08\x6c\x86\xf7\xad\x7f\x94\x4c\x14\xff\x87\x4c\xfc\x1f\x32\xf1\x7f\xc8\xc4\xff\x63\x32\xe1\x0e\x06\xe6\xf4\xc9\x6b\xf2\xe1\x1f\xc1\x1f\xfb\x33\xf8\x8f\xac\x2b\xa4\x9c\xc9\x9b\x82\x01\x09\x7f\x04\x56\xc8\x08\x94\xff\x2d\x32\xf1\x17\x5e\xfa\x3f\xe2\xfd\xbf\x23\x13\xab\xe4\x7c\x2d\x67\xf6\x0a\x64\x40\x7f\x04\xff\xe6\xcf\xe0\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\x3f\x6d\xf9\xcf\x0f\x48\xdf\xd8\x18\x96\x0c\x36\x59\xd7\xca\xbc\x61\xf5\x59\x01\x41\xed\x36\x45\xf0\x62\x1b\x91\x17\x2f\xcf\x8b\xb1\x83\x52\x12\x3d\x58\x7c\x14\xd7\x65\xe3\x74\x14\x1d\x5a\x0a\x4b\x5e\x30\x95\x56\x52\x9f\x81\xdf\x6f\x64\x9a\xab\x74\x36\x28\xf4\x77\x9a\xe9\x68\x4d\xe6\xc2\xb7\xdf\xf8\x7d\x68\x09\xd2\xdf\x85\x7a\xcb\xfd\x50\x5c\x0b\x6e\x63\xa2\x21\xb1\x81\x16\x82\xba\xe7\x32\x04\x6c\x7d\x08\xfe\x4a\x02\x3c\x89\xcc\x84\xa9\x9c\x74\x0d\xd1\x07\xe8\x6c\xd9\x6d\x50\x78\x00\x28\xab\xc0\xf5\xbc\xc9\x1e\x25\xec\x51\x13\x0c\xe6\x2b\x0e\x4d\x45\x33\x49\xcc\x26\x43\xee\x43\xa8\x04\xee\x42\xea\x8e\xc1\xf8\xad\x51\xb4\x12\x6d\xa8\x14\x9d\x30\x20\x06\x63\xdd\x79\x10\xf5\xcb\xfe\x40\x41\x27\x2e\xd1\xa6\xae\x92\xf1\xe0\xbc\xf9\x59\xfc\x86\x67\x8a\xbd\x64\x14\xc2\x44\x6c\x03\x8e\xaf\xa6\x1b\x32\x6c\x1b\x2b\x98\xd1\xf1\xa5\xc7\xfa\x27\xc1\xc5\x29\x8e\x6c\x16\xad\x9d\xf6\x64\x8a\xed\xe9\x09\xc1\x65\x1c\x8d\x36\x8d\xd3\xbf\x9d\x93\xba\x43\xe5\x78\x9f\xee\x2e\x97\x94\xd9\x45\x17\xe9\x07\x5e\x67\x5e\x24\xb0\x4b\x4b\x68\xec\x65\xb5\x5d\x66\x36\x19\x04\x24\xf4\x7a\x67\xe2\x73\x9d\xe4\xaf\x5e\x29\x11\x5f\x23\xfe\x00\x36\xd3\x58\x11\xa5\xeb\x65\xe9\x2e\xcb\x88\xbb\x4c\x00\x45\x41\x6e\x61\x2c\x1b\x9f\xc3\xd2\xa7\xbd\x72\x71\x60\x75\x68\x9a\xce\x21\x92\xeb\x47\x86\x04\x04\xd0\x1f\x99\x0d\x0c\xd2\xd4\x32\x5d\xb8\x22\xd5\x5a\xb8\x88\x87\x15\x36\x3a\x8c\x48\x9f\xa7\x06\x6c\xe2\xfe\x8e\xc3\xb7\x3b\xcf\xaf\xc8\x9c\x09\xc2\xda\x32\x1a\x5c\x0a\x35\xbe\x7a\xa5\x7f\x0e\x5a\x33\xe2\x77\xd2\x76\x4b\x00\x91\x51\xf7\x23\x01\xae\x12\x5b\xe6\x48\x9f\x6b\xd3\x43\x39\xa3\xdb\x47\x2f\x7e\x0d\x6f\x1b\xa4\xac\xdd\x58\x95\x64\xca\x26\xcd\xe4\xbc\x2e\x05\x1f\x21\x57\x48\x1b\xf6\xa8\x3e\xd2\x1c\x05\x56\xd7\x5e\x36\x99\xa1\x41\x72\x48\xe5\xc5\xc4\xfb\x01\x14\x04\x6c\x12\x17\x55\xe9\x02\xa6\x2e\xcd\x32\xa4\xa0\xfd\xc5\x0f\xb0\xbb\xbf\x18\x21\xda\x18\x07\xc2\xec\xf1\x2b\xe7\x83\x93\x64\xb3\xb3\x98\x2f\x4a\x1b\x41\x73\x70\xe7\xc0\x47\x65\xd3\x97\x3e\xcf\x62\xcf\xf1\x0b\xf7\x45\xac\xdb\xc7\xbc\x74\x1b\x20\x25\x61\xac\x66\x08\xa3\x40\x00\xc6\x27\x06\xbf\x1c\xe2\x57\xd1\x5c\x07\xff\x9b\xd2\xa9\x16\x8f\xaf\xba\x5b\x39\x29\xea\x3b\x48\x18\x23\x9d\xc2\x2c\x75\x46\x5d\x94\xff\xc9\x44\xe0\x68\xb2\x7f\x97\xed\xfe\xdf\x1c\xff\x8e\xe0\x1a\x82\x28\xba\x2b\x75\x6b\x8e\x20\xab\x21\x11\x6a\xe1\x09\x8e\x9f\x07\xca\x3d\x2f\xdf\xb3\xb2\xc5\x55\xad\x95\x60\x43\x9a\xbd\x34\x85\x0f\xde\xa3\xe9\xc3\xe4\xa0\x68\xb9\x30\x71\xad\x18\x24\x9a\x14\x1e\x3a\xe4\x22\x8d\x7e\x98\xdc\x88\xa6\x70\x8a\x02\x9f\xc7\x8c\xcb\x3c\x55\x9f\x55\x81\x16\x40\x93\xe8\x75\xa5\xc2\xfe\x62\x6a\x32\x6f\xa5\x6d\x9c\x84\x3b\x78\x4e\xe2\x20\xb4\x2a\x0c\x2c\x60\xa7\xc5\x6f\x1f\x7f\x87\xdd\x3a\x23\x82\x86\x69\x41\x81\xc7\x8f\x56\xe0\xd7\x90\x1b\x48\x60\x28\xf9\xc7\x1a\x10\x36\x86\x22\xd3\x2e\x09\x4a\xd5\x9e\xc7\x3b\xa1\x89\xae\xb5\x16\x52\x12\xa9\x15\x4f\x2a\x8f\xc4\x05\x3f\xf9\xb8\x05\x68\xa5\x17\xe8\x8a\x84\x62\xda\xff\x08\xa0\x71\x9a\x7b\x9f\xdb\x4f\xf2\xcf\x8d\x30\xdb\x9d\x18\x92\x74\x8b\xfb\x5b\x87\x24\xb1\x15\x46\x34\x20\x20\xab\x9e\xef\x68\x87\x25\xe9\xf8\x05\x9a\xe9\xee\xda\xb0\x56\x8a\xc2\xae\x9a\xe2\x1e\x0a\xac\x92\x45\x4c\xb6\xb1\xdb\x16\xa0\x61\xb5\xf1\x8d\xf3\x03\x97\x4a\x12\xf2\xc5\x4c\xd6\x7f\xa2\xb2\xb0\xc6\x35\x37\xf0\xbb\x2a\x9a\xb5\x4d\x36\x0a\x49\x11\x6a\x29\x42\xd1\x4d\xcb\xf5\x8d\x8f\xfb\xe2\x6e\xc3\x88\x37\x2f\x30\x8a\xc5\x0f\x5c\x31\x29\x46\xd9\x39\xfa\x6e\x96\xd1\x6d\xa4\xa5\x3a\x36\xd4\xfa\x09\xc1\x01\x67\x6c\xab\x6d\x68\xdc\xcd\x8f\x96\x6c\x22\xfd\x3a\xf9\xe6\x2a\xdb\x6e\xbc\x00\x24\xbd\x2f\x46\xe6\x5a\x13\x44\xb1\xa7\x1f\xbc\x60\x0a\xf8\x5d\x1e\xe7\xe6\x30\xfe\x84\x43\x22\x1c\xce\x76\xee\x4a\x95\x70\x53\x72\x9c\xe6\x5d\x48\xd5\x3b\x7f\x29\xf4\x58\xf6\x27\x7d\x31\x3c\xf3\x76\xad\x2e\xe4\xbf\x88\x49\x5b\x6b\x09\x57\xf4\x23\xba\x8d\x0d\x3a\x16\x66\xb0\x59\xa8\x6f\x4e\xd8\xf3\x41\x07\x0d\xcc\x6f\x04\x7c\xc6\x7b\xfe\x01\x16\x5f\xf8\x56\xb8\xa4\x26\xfa\xe0\x28\x99\x30\x32\x86\x85\xba\xe9\x7b\x20\x33\x00\x23\x2d\x48\x04\x60\x5c\x84\x37\xbb\x79\x76\x41\xce\x8e\xf0\xa5\xda\x27\x18\x93\x79\x7e\xd7\x43\x91\x4d\xc2\x49\xdc\x13\x0b\x5a\xa8\x5e\x5c\x24\xee\x12\x5a\xb5\xf0\x65\x82\x2a\x66\xf1\x84\x55\x62\x01\x47\x2d\x90\x84\xfa\x31\xe9\x4b\xba\x7c\x2b\x74\x27\x38\xd3\x25\xd2\x31\x21\xb6\xa4\x88\x81\x5d\xf2\x02\x52\xa1\x5b\x86\x37\xd6\x42\x23\xed\x36\xb4\x95\xa6\x35\xc5\x10\xdb\x49\xda\x1a\x0e\x21\x9c\xdf\x20\x3c\x47\x48\x0e\x36\xdc\x5a\xc3\xb6\x5f\x28\x40\x42\x56\x0d\xb1\xee\x80\x84\xe5\x12\x66\xbb\x34\xed\xf5\x4c\xb8\xd0\xb2\x80\x6d\x40\xad\x99\x02\x74\x8d\x78\x76\x9f\xde\xd2\xf6\x55\xd7\xe7\x6e\x55\x87\x3d\x73\x04\x8d\xe0\xb8\x1a\x99\xb4\x1d\x6d\x69\x33\x39\x6b\x51\xfa\x3c\xa3\x67\x47\x23\xea\xdc\xcd\x9c\x29\xbf\x88\x72\x8c\x96\xc7\x31\xe4\x0a\xf2\x07\x8c\x30\x7a\x22\xf7\x0d\xbb\x30\xc5\x60\x58\x6b\xeb\x50\xa1\x27\x73\xe6\xcf\x77\x81\xff\x9c\x86\xf0\x68\xbe\x7f\x99\xef\xf8\x7b\xeb\xd2\x7f\xda\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\x93\x10\x4c\xee\xdf\xcf\x72\xfe\x53\x49\xb8\x25\x9f\x1c\xed\xc7\xf8\x4b\x54\xb3\x88\x02\x61\x7c\x03\x75\xcf\x4c\xa9\xa5\x59\xa8\x81\xf5\x05\xba\x68\xe1\x25\x29\x21\xff\x85\x0f\xdb\xc6\xa7\xec\xb5\x13\x82\x27\x12\xab\xba\xce\xca\x24\x2c\x2f\x44\x6b\x26\xd8\x42\x3b\xec\x65\xb8\xe6\x6f\xff\x5d\x95\x85\x19\x75\xca\x73\x7e\x94\x67\x67\x55\x17\x24\x4a\xd8\xca\xd7\x59\x0c\x49\x5a\xb6\x8c\xbc\x2a\x57\x78\x52\xd9\x20\xe7\xb0\x3b\x8c\xb6\xd4\xe2\x72\x82\x64\xf8\x3b\x18\xcf\x5d\xaf\xd0\x7c\xe7\x1e\x46\x6b\x22\xb6\xda\xbe\xa1\x64\x66\x34\x7c\xc5\x29\x5f\x50\xb7\x80\x0b\x3d\x93\xc0\xf6\x07\x46\xe6\xfc\x1c\x28\x34\x00\x5a\xcb\x57\xd2\x08\xa0\xcd\xaf\x13\x03\x9f\xee\x95\xf3\xb9\x48\x98\xbb\x76\x61\x3a\x6d\x72\x09\xe4\x17\x8b\xd6\x77\xaf\xa9\xfc\x92\x56\xe3\xe5\xa9\x5f\x43\x42\x7e\x97\xc3\x97\xec\x78\x2b\x69\x76\x3a\xf8\x59\xb7\x30\x72\xdc\xdd\x12\x60\x02\x30\x27\x01\x6c\x2a\x2e\x67\x2a\xfc\x0e\xb0\x07\x42\x4d\xf1\xf7\x50\xa1\x79\xa6\x24\x4d\xf4\xf4\x06\xf2\x0d\x73\x2f\xd3\xbd\x71\x63\x37\x32\x93\x08\x89\x02\x76\x73\xca\xcc\x8c\x43\x6f\x61\x2f\xf0\x83\xd4\xc6\x8c\x91\x65\x27\x62\x3b\xf1\x90\x0d\x2c\x9c\x97\x29\x9c\xec\x10\x7b\x06\x62\x6d\x99\x30\x93\x6e\x2d\x0a\xe6\x56\xa4\xe0\x45\xb8\x50\x15\x53\x65\x1e\xb4\xf1\x55\x99\xed\x41\x7d\x0c\x54\x0c\x69\x52\x87\x2a\x52\x22\xef\xc3\xb5\x46\xc1\xd7\xb2\xcd\xd1\x97\x8f\x3d\x9c\xf7\xb8\xa4\xa5\x7e\xbe\xc2\x53\x3b\x74\x57\x4f\x15\xf2\x90\x74\x18\x25\x85\x6b\xc3\x50\xd5\xe2\x13\xd4\x02\x46\x1a\xb0\xb9\x0c\xb9\x3a\xb0\xaf\xe0\x8c\xc4\xa1\x03\xcb\xc9\x28\x80\x11\xdc\xb9\xd8\xce\x49\x9e\xa9\x5a\x01\x7a\x5b\x03\x3d\x98\x8c\x55\xbc\x2b\xf1\x0c\x4e\xd4\x81\xc5\xb0\x0c\x0d\x4a\x3b\xb7\x66\x8a\x7c\xff\x28\xd1\x6a\x1d\x0a\x41\x2d\xdc\xad\x23\x82\x38\x02\x89\xe1\x5b\xf3\x45\x5d\xd3\xe5\xfb\xc2\xc4\x60\x59\x7f\x4a\x87\x52\x89\x3e\xf1\x77\xcb\xd1\x6b\x4b\x65\x35\xac\x06\x76\x04\x3c\x97\xec\x68\x17\x53\xd2\x7c\xd8\x38\xc4\x2a\x94\xd3\xa7\x8c\x7c\x21\xad\x85\x0d\xbc\x0d\x6d\x44\x7f\x9c\x6a\x29\x9f\x1f\x12\x0c\xbf\x23\x2e\x7e\x8e\x09\xcf\x9b\x43\xd2\xaf\x10\xdf\xfe\x44\xe0\xe3\xc2\x66\xb8\x51\x18\xb8\xe0\xe0\xe9\x9d\x74\x30\x43\xc8\x63\xf8\x12\x59\x60\x43\x39\x0b\xba\x99\x12\x00\x1c\xf4\x27\x87\xc0\x40\x5c\xe4\xca\x2e\x69\x06\xde\xbe\x2a\x58\xb4\xb5\x1b\x1f\xfa\x29\xf4\xe8\x6b\x1a\xe0\x04\xbf\x2a\xac\x4f\x67\x1b\x0c\x3a\xe7\x4c\xf8\xdd\x7f\x91\x16\x3f\xe5\x61\x37\x97\x57\xdc\x01\x33\xe1\x54\x9c\xe2\x48\x04\x13\xce\x6b\x1f\x5d\xed\x06\x5f\x87\x53\x94\x94\x0b\x1d\xfc\x1d\xb2\xbd\x5f\x37\xc3\x61\x27\x47\x6f\xed\xbc\xa7\xd7\x3f\xdc\x94\x70\x3c\xff\xb2\xae\x84\x4a\xfd\xef\x42\x42\xf0\x3b\x2c\x09\x16\x1c\xbb\xde\xdf\xb8\x7b\x3f\xb6\x39\x15\xd5\x7b\xb9\x36\x65\x59\x41\xe4\xb4\x55\x93\xf5\x85\xa8\x9a\x55\xf8\x99\x33\xc5\xc9\x8d\x4c\x35\x43\xaa\x74\xbe\xa7\xc4\x7a\xab\x32\x11\xd7\x0c\x8b\xd1\xb8\x86\xd7\xb9\xac\xa7\x21\xf4\x87\xbd\x34\xa0\xc0\x25\x28\x73\x3f\x31\x47\x0d\xdf\x9e\xe7\x7e\xf8\xc6\xd5\xf1\xde\x39\x01\x6a\x9b\x84\x6a\x49\x44\x1a\xe7\x64\x5f\xee\x23\xc6\xba\x2c\xe9\xe0\xfc\xd5\xd7\xef\xd7\x57\x3b\x41\x12\x48\x95\xa3\xc7\xe7\x10\xf4\x29\xaa\xb7\xbd\x6f\x96\xcd\x01\x06\x2b\x4c\xcf\xb3\xb6\x1d\x76\x8c\x01\x6e\x49\xd3\x6e\x7d\x19\x1b\xe9\x05\x60\xd1\x8b\xa2\x84\xad\x57\x74\xe5\xf0\x4a\x29\x75\xc9\x04\x32\xcb\x87\xa7\x8d\x99\x82\x15\x7b\x45\xf8\x3d\x53\x7b\x99\xc8\xb2\x45\xb1\x40\x42\xb4\xbd\xd7\x77\xe6\xd3\xfa\x3a\xbf\x1e\x14\xe3\x81\xc4\x0b\x27\xf3\x04\xa3\x32\xe2\x80\x7a\xde\xc1\x66\x40\xb9\x2f\x41\x02\xd4\xdd\xe2\xed\x85\xf5\x40\x3a\x52\x66\x2a\x8c\x41\xfc\x4a\x4f\x23\x2d\xb0\xd4\x2c\xd4\x9f\x1e\x21\x7b\x0a\x46\x05\x59\xd2\xb8\x38\x63\x54\xe1\x39\x41\x8c\xb5\xca\x8e\x11\x78\x88\xfa\x75\x0e\x8f\xfc\x3a\xeb\x57\x3d\xaf\xbb\x24\x05\xca\x5d\x3b\x93\xeb\x12\xc3\xf4\x69\x93\x91\x57\x93\x4a\x08\x1a\x19\x5c\xc9\x5e\xcb\xa3\xa9\x05\x4a\xf8\x2e\x3b\x1a\x5d\x96\x21\x2a\xfb\xf6\xe6\xb6\xf1\xd4\x36\x24\x05\xbc\xf6\xbc\x46\x66\x79\xf5\x02\x60\xd2\xfe\xa2\xb1\xd6\xf6\xbb\x5d\x3b\xce\xa5\x89\x4c\x08\xe8\x05\x07\x1c\x01\x6d\x90\xe5\x0a\x23\x7e\x42\xbc\x02\x41\x72\xd6\x99\xa8\xeb\x17\xae\xf9\xe0\xd1\x3f\xa0\x5c\xec\x1f\x2c\x58\x51\x9a\x39\xd0\x2b\x2e\x4f\x83\xd8\x85\x2b\x2c\xbb\xc0\x28\xd8\x79\xa5\xad\xba\x7e\xa2\x61\x03\x85\x17\xbb\xf9\x06\x40\x18\xea\x1a\xd9\x5c\x7d\xc0\x61\x46\x9a\xa1\x10\x92\x09\x35\x50\x0a\x61\xb2\xe8\x02\xe6\x62\x72\x20\xf4\x3e\x24\x4c\x56\x75\x6a\x79\xf9\x97\xa0\x4c\xe1\x62\xd6\x8a\x30\x12\x83\xaf\x60\x84\xc2\x3f\xba\x82\x2e\xb3\xf1\x7e\x2d\x6d\xdd\xdc\x6f\xad\xb8\x61\xbb\xd2\x73\xf3\xdf\x7c\x5e\xdd\xed\x01\x7f\x08\xd7\x5f\xd7\xcd\xf0\x8c\xca\x81\xe4\xf8\x31\x9f\x33\xdd\xff\x64\x20\xbe\xb3\xeb\xdf\x65\x6b\xab\xf8\x77\xf2\xfe\x1f\x29\x9f\x1d\x1f\xab\x96\xc7\xd0\xbd\x05\x8e\x16\x3a\x86\x58\x2a\xb1\xc3\x9a\x9c\xc3\xee\x10\xa1\xd9\x00\x4b\x59\xbc\xd4\x02\x46\x8d\xe5\x20\xa6\xec\x92\x80\x63\xc3\xd3\x16\x06\xfb\x1b\x56\x32\xb1\x9c\x86\x75\x2f\x4f\x93\x48\xb4\xbe\xf6\xdf\x41\x59\xc7\x92\xed\x03\xf4\x4c\x25\x90\x93\xdf\xfa\x7c\xd7\x44\x09\x28\x58\xb8\xbd\x3d\xcc\xdd\x7b\x8e\x11\x64\x8a\x2f\xa2\x2e\xfc\x20\x30\xcd\x69\x8d\x6b\xac\xd2\x2b\xaa\x53\x06\xbb\x85\x23\x66\xd1\x89\xfc\x64\x15\xb5\xc6\xa7\x3b\x16\x92\x45\x6a\xb6\xde\xd6\x3e\x1f\x06\xdb\x1d\x34\x5d\xa3\x1a\x2f\x16\xb5\x13\x31\x0a\xb1\xdc\x3f\x49\x8d\xc6\x33\xfb\xba\x26\xe4\xb0\x20\xa2\x65\x32\x99\x1f\xc6\x18\x3c\x8b\xab\x32\xc5\xbb\x69\x6d\x69\x65\xed\x41\x02\xbc\x8a\xd1\x33\x80\x14\x97\x3f\xdf\xef\x1c\x17\x7b\x0e\x0c\xfa\xad\x62\xbf\xa6\x9e\x0c\x9e\x97\xa2\xed\x9a\xab\x98\x4b\x3d\xda\xe4\xc9\x69\xb9\xf0\x96\x36\x79\x0a\x37\xe8\x97\x22\xf8\xf5\x58\xf0\x5f\x30\x9c\x2a\x66\xbf\x68\xc2\xab\xeb\x4b\x38\x92\x6a\x67\xef\xc6\x02\x66\x5f\x03\x18\x1a\xeb\x08\x02\x1d\x50\x71\x5b\xe9\x50\xff\xcc\x78\x67\x83\x2d\x3d\x1b\x9e\x21\xb8\x5c\x2f\x99\x8e\xb9\xb3\x6a\x80\xd3\x80\xd6\x27\x9b\x72\x5b\xc2\x23\x29\x69\x97\x9e\xde\x5a\x69\xb1\xfc\x34\x35\x0b\x53\xa5\x65\x1b\x89\xf1\x3e\x0d\x81\x6f\xf0\xce\x7f\x33\x37\x50\xd5\x19\x03\x82\xc1\xf4\x59\x96\x9e\xb6\x5c\xde\x41\x29\x87\x62\x32\x9e\xa7\x64\x4b\x9c\xe5\xde\x77\xd2\x37\xf8\x6f\xb3\xee\xa2\x70\x07\x00\x0d\x1e\x48\x11\xae\xf9\x98\x76\x53\xc2\xd2\x29\xc8\x5e\x1d\xbc\x99\x5b\x93\x03\xb3\x4e\x6b\x5f\x33\xa1\xd4\xcd\x6e\x9a\x5b\x6a\x6a\x53\xc1\xd5\x60\x5e\xf9\xc5\xb5\x81\x31\xfc\x61\xf7\x04\xf5\x98\x8d\x6a\x36\x48\xc1\x08\x8d\xec\xce\xab\xde\xf8\x54\xb7\x25\xc8\x3c\x16\x92\x4e\x89\x05\x26\xf4\x23\x1c\xf2\x04\xa6\xfd\xb6\xbb\xde\x7e\x6c\x11\x3f\x58\x68\xb5\xc9\x84\xb9\xbb\xd9\xc8\xf9\xae\x8a\xd6\x9b\xfa\xbb\x03\x1b\x26\xd0\x16\x4b\xbb\x04\xe3\x20\x76\x86\x0f\xf8\x8e\xb8\x1a\x77\x6c\xf5\xd2\x1a\x37\x02\x10\xdf\xd2\x00\x9b\xf8\x2a\xaa\x87\x66\x72\xd5\x76\x36\x89\x74\xae\x9c\xcb\xe6\x1c\x6f\xad\x90\xc6\xaa\x05\x16\x2e\x36\x5a\xbe\xac\x65\x46\xd4\xf9\x96\x6c\xc3\xca\x81\xdf\x6e\x8e\xc6\x0d\xe8\x24\xa4\xa0\xbe\x04\x12\xe0\xb2\xdd\xa2\x5a\x64\x98\xfd\x98\x5b\x60\xe6\xa3\x4f\xec\x2e\x08\x22\x5a\x6e\xb1\x1c\x71\xc9\x81\xee\x69\xaa\x35\x51\xf2\x89\x1e\xaa\x96\x98\x03\xad\x14\xa6\x0c\x0d\x7d\x06\xce\xe0\x02\x72\x44\x73\x2b\x8f\x4b\xfb\x54\xed\x58\x3a\x0f\xe9\x5e\xf9\x90\xa5\xfe\xc1\xac\x76\x5d\x25\x29\xd1\xa5\xcb\x51\xd0\x98\x55\x90\xfc\x59\x07\x50\x44\xe1\xfc\xf3\x34\xfe\x67\xa8\xef\xd0\xd5\xb7\xc9\xae\x5c\x23\x80\x01\x33\x8e\x42\x7c\xd6\x13\x7f\x52\xe9\x58\xd7\xd7\xff\x8f\xb9\x2f\x6f\x6e\xd5\x58\xfb\xfc\x3f\x9f\x82\x72\xe6\x4e\xee\x1d\x85\xa5\xd9\xf1\x39\x27\xf5\x22\xa1\x1d\xed\xbb\xa6\xa6\x6e\xb1\x83\xc4\x26\x40\x20\xe4\xf1\x77\x9f\xea\x46\xb2\x65\x5b\x3e\x49\xde\x9c\xb9\x15\x27\xc7\x82\x5e\x9e\xfd\xf9\x75\xd3\x36\x7e\xf2\x40\x5c\xcf\x26\x12\x85\xfe\xe6\x11\x15\xb7\x04\x83\x12\x23\x76\xfc\x83\x0f\x05\x8a\xe0\x33\x5c\x79\xb8\x01\x96\x34\x77\x6a\xa7\xc0\xff\x62\xb8\x5a\x92\x5a\xd9\xb7\x63\x66\x8b\xbf\xfe\x83\x69\xa4\xb9\x83\x2a\xc6\xaa\x5a\x69\x25\xff\xa6\x7f\xc1\x4e\x81\x1f\xa6\xdf\x7e\x71\xb3\x2c\x7e\x24\xc9\xa2\x28\x88\x82\x21\xa2\xc4\x21\x69\x8a\xa2\x20\x99\x5f\xb0\xdc\xb3\x8a\x7a\x74\xfa\xf6\x0b\x85\x51\x98\x40\x63\x80\xa2\x5e\xca\xbd\x96\xbe\xf5\x7b\x65\x69\xc1\x1f\x2b\x4b\xcb\xf0\x04\x5d\x15\xa5\x05\x14\xa8\x2a\xd2\x5e\x9a\xe0\x15\x41\x51\xdc\x0f\x2f\x47\x6b\xd1\x86\x69\xb1\xf7\xeb\xa1\xde\x29\xcf\x6a\x51\x86\xf6\x59\xf9\x57\x06\x30\x1f\xcb\xbf\xea\x06\x65\x9a\xf7\xc7\xb3\xec\x9d\x72\xb1\xb4\x0e\xcc\x4f\xc4\xe1\x84\x8f\xe5\x59\x0d\x41\x32\x8d\x4f\xca\xcb\xf2\xd2\xc7\x6a\xba\xba\x26\xb2\xfa\x67\xe5\x65\xc1\xc7\x72\xb7\x9a\xce\x8b\xda\x27\xe3\x25\x86\xfd\x58\x01\xd6\x60\x39\x49\xfc\xff\x5e\x2e\x76\x29\x49\x1d\x82\x5e\x02\x97\xe5\xee\xd7\x8c\x05\xbf\x5b\x33\xf6\x23\x89\x3f\x5b\x38\xf6\x3d\x7d\x89\x00\x98\x04\x08\xa0\xb2\x84\x80\x09\x34\xc1\xb9\x0c\x21\xf9\x34\x21\x62\x80\x46\xf5\xd4\x59\x1c\x5e\xb8\x2c\xc1\xf9\x0c\xc1\x60\x80\xc1\x68\x42\xc2\x01\xe3\x32\x84\xe8\xe3\x2c\xc1\x63\x40\x24\x78\x17\x67\x55\x20\x60\x82\x40\xd0\x3e\xce\x10\x02\x06\x18\x42\xea\x48\x04\x38\x07\x34\x4d\x00\x8c\x5a\x22\xda\x1c\x21\xf8\xa8\xe2\x38\x4d\x08\x57\xda\x02\x6c\xcd\x2b\x22\x0c\xc1\x2d\x05\x9e\x60\x2f\x34\x58\x42\x80\x6d\x02\xba\xc5\xe1\x6d\x7e\x6d\xe3\x51\x39\x71\x01\xa3\x7c\x9c\x87\x7d\x70\x3a\x4b\x00\x9f\x85\x92\x33\x84\x88\xb1\x55\xc1\x78\xd1\x65\x55\x9e\x46\x2a\xba\x38\x4b\xbc\x56\xeb\xfd\x07\xcd\xd8\xb6\xfd\xbb\xb5\xa9\xe9\x3f\x06\x02\x40\xbc\x82\x00\x47\x11\x14\xcd\x54\x38\x70\x69\xa5\x5f\x5b\xff\x12\x10\x54\x58\xf2\x3e\x1e\x79\x86\x95\xee\x97\x8e\xfe\x18\xbc\x02\x05\x18\x5e\xff\x6e\xf0\x7e\x6a\x09\xe6\x0f\x5a\x02\x10\x1c\x00\x17\x5b\x00\x42\x00\x97\x2a\xdd\x3c\x47\xd0\xa8\x9d\x7e\x6d\xff\xfb\x5b\xe3\x25\x4f\x78\x96\x60\x30\x8e\x23\x38\xe3\x5a\x99\x1f\xd5\x9b\x67\x70\x8e\x00\xf0\x43\x20\x18\x54\xc9\x1d\xe5\x08\x0c\x3d\x11\x65\x8f\x30\xa3\x25\x82\xc7\x78\x86\xe0\x31\x1a\xf6\xf1\xac\x01\x67\x12\x74\x35\x83\xc7\x45\x82\xc3\x69\x54\x2b\xbf\x2a\xc9\x2e\xc2\x24\xc0\x01\xce\x41\x2e\x3c\xfa\x40\xf4\x20\x57\x38\x0e\x08\x44\x55\x63\x1e\xa3\xab\xda\xf8\x55\x1e\x5d\xaa\xc4\x83\xaa\x20\x3d\xc1\x63\x30\x07\x04\x02\x54\xa9\x88\xca\xfa\xd3\x14\x0e\x08\x0e\xe3\xab\x62\xee\x30\x07\x59\x1c\xd5\x6e\x97\xd0\x05\x8f\x08\x11\x34\xc6\x13\x12\xaa\x53\x4f\x11\x0c\x46\x05\xb8\x44\x48\x18\xe0\x08\xc6\x20\xb8\xaa\x7c\x3d\xd4\x17\x43\xd5\xe6\x69\x64\x06\xa1\x52\x1f\x92\x05\x04\x8d\xf3\xa8\x19\x00\x42\x82\x38\x21\x60\x34\x2a\x10\xcf\x62\x04\x8b\x09\x84\x08\xa7\xd2\x18\x8b\x24\x10\x90\x4a\x1c\x94\x84\xc7\x69\x42\x08\x68\x88\x07\xc0\x05\x04\x30\xa0\x28\x2c\xaa\x37\x4f\x57\x55\xe7\x71\x54\xb3\x9f\xc7\x01\x4c\x70\xfc\xa5\x52\x3d\x83\xe4\x70\x01\xc1\x2d\x19\xb1\xaa\x4c\x4f\x61\xa8\xc2\xfe\x45\x0b\x42\x38\x07\x2c\x46\x21\xe9\xe1\x5c\xaa\xb2\x12\x72\xde\x2d\x7d\x34\x37\x47\xc3\xa1\xf0\x1c\xc1\xb8\x84\x64\x7c\x18\x86\x03\x24\x19\xf4\x09\x2a\xe8\x8f\x2c\x09\x05\xc1\xa1\x86\x06\x21\x10\x34\xf4\x0e\x94\x0e\x9a\xeb\x52\x77\x1f\xdd\x54\x5e\xe2\x91\x13\xaa\x29\x0c\xba\x03\x50\x62\xbe\xaa\xc4\xcf\x56\x22\x13\x1c\x51\x4d\xb9\x94\xfa\x47\xff\xf3\x30\x52\x2a\x32\x12\xd4\x05\xc6\x0c\xec\x95\x08\x16\xd2\x82\x32\x8b\x48\x60\x54\xd2\x1f\xc9\xc7\x60\xd4\xa5\xe6\x3f\x80\x91\x55\xc9\x8b\x43\x21\xa1\xb6\xd7\x40\x40\x28\x2d\xc2\xe0\x63\x0d\xa8\x2e\x53\xb9\x19\x99\x4a\x22\xa0\x3f\xf9\x4a\xa3\x4f\x45\x61\x2a\x67\x41\xc2\x48\x2d\x0e\xa3\xa1\x2c\xc8\xe4\x17\x37\x5c\x87\x88\x70\x1a\x6a\x84\xe6\x70\x71\x42\xaa\x78\x56\x62\x33\x38\x0a\x60\x80\xd0\x1d\x1a\x5b\x34\x70\x18\xe7\x04\xc0\xd1\x18\x1a\xe7\x90\x5d\xa1\x56\x70\x21\xa1\x60\x4c\xc1\x1b\x50\x45\x3e\x6c\x61\x08\x9e\x00\x18\x07\x63\x6d\xc0\xc0\x41\x2c\x20\x78\x83\xe0\x08\x1a\xb1\xa0\xaf\x26\xbe\x18\xaa\x12\x0f\x1a\x1b\x79\x43\x82\xc2\xd1\x95\xb3\xa0\x91\xa0\x67\xa1\xdb\x72\x00\xc3\x41\x42\x83\xe9\x6a\x0e\x52\xe2\xd5\x9e\x08\x15\x90\xb0\xdc\xc5\xbe\xa0\xca\xcb\x73\x80\x73\x04\x03\x65\x80\x96\x81\x56\xe5\x61\x3a\xc2\xe4\x84\x21\x59\xb9\x99\x7b\x21\x86\x23\xbf\xd0\x2f\xd4\x90\xdf\x08\x09\xb5\x56\x06\x16\xa0\x81\x3b\x40\x30\x50\x47\xe5\x87\xd7\xf1\x2c\xe2\x4b\x57\x64\x18\xe8\x3d\x44\x19\xbb\x62\x04\xca\x1a\x16\x03\x06\x01\x30\x16\x3a\x08\x93\x90\x77\x59\x88\x14\x02\x26\x62\x70\x2c\x14\x1e\x2e\xd2\x40\x22\x68\x9c\x85\xd2\x71\x38\x43\x48\x04\xc0\x45\x28\xa1\x00\x33\x15\xe5\x7a\x85\x76\xd0\xb4\x28\x4f\x20\x5a\x30\xe7\x00\x4e\x10\x5f\x12\x99\xab\xbc\x4d\x63\x14\x94\x10\x66\x1a\x67\x54\xda\xbf\xda\x02\x19\x09\x41\x84\x01\x07\x62\x48\x72\xb6\x4a\x36\xc4\x11\x51\x81\xae\xc5\x11\xa1\x2a\x9a\x58\x68\x52\x98\x07\xd0\xf8\xd5\x07\x87\xc2\xe8\x12\x0e\x55\xe6\x41\x36\x1c\x62\xc3\x12\x2c\x86\xe0\x13\x92\x83\x12\x40\x1f\x4b\x18\x82\x49\x02\xea\x8b\xf0\x08\xe2\xd5\x35\x68\x05\x9c\x45\x81\x08\x15\x17\x2b\x28\x66\x10\x6e\xd1\x04\x83\x23\xd8\xe6\xaa\x24\x94\x08\x11\x82\x3c\xcc\x42\x18\x82\x50\xc4\x1b\x39\xf1\x17\x7d\x85\x4b\x88\x43\xdc\xac\x74\x62\x09\x29\x60\x59\x04\xc0\x74\x65\x33\xe6\x8a\x3a\xe0\x9a\x26\xaf\xe0\x04\x75\x62\x73\x08\x74\x50\x9b\x8a\x1c\x84\x14\x2a\x47\x76\xc5\x11\xeb\xca\xd8\x50\x6b\xfa\x1c\x08\x08\x0b\x58\x17\xd2\x80\x6d\x15\x4c\x12\xa0\x0a\x46\x14\x90\x1c\x42\x3d\x1c\x40\xba\x37\x22\xb0\xd7\xb0\x46\x1f\x1f\x20\x07\xfa\x0e\xd2\xb9\xc0\x43\x15\x5e\x02\x54\xfa\xa2\x99\x74\x05\x0c\x0e\x91\x12\xf1\x2b\x45\x64\x5a\xbe\x8a\xeb\x0a\x32\x58\x0c\x32\xe7\x2a\x04\xe5\xab\x9c\x60\xbe\x3b\x5d\xac\xa6\xb3\xe7\x01\xe0\x30\x4e\x30\x6e\x9d\x2f\xa0\x64\x80\xee\x43\x32\xa3\x20\x45\x66\x67\x10\xb2\xa0\x05\xc4\xa8\x7c\xc2\x42\x42\x28\x40\x24\x64\x0a\x08\x6f\x08\x17\x10\xa7\x2a\x7a\xc5\x6a\x46\x25\x2a\x5c\x60\x0d\x70\x1d\x2b\x5e\xc6\x4a\x2f\x50\xc6\xde\x40\xd9\x2b\xce\x23\x9f\x09\xc6\x15\xe8\x99\x17\xd8\x11\x91\xc7\x30\x24\x36\x5f\xad\x70\x0c\xbc\x87\x61\x7f\xb5\xf5\x00\xf0\x18\x4f\x41\x30\xbc\x64\x03\x8d\x23\x84\x81\x7c\x61\xd8\x56\xab\x3e\xf6\xb2\x2a\x82\x6a\x8b\x60\x20\x0f\x13\xe0\x02\x5b\x0c\xd4\xe3\x15\xbe\xa0\x76\x97\xf5\x09\xa1\x38\xe4\x5f\xa9\x42\x88\x57\xd4\x83\x4b\x93\xf8\x06\x3c\xd0\x8a\x72\x6d\x83\xb9\x88\x22\xe5\xb2\xb4\xa0\x98\x93\x2e\x12\x02\x0c\x51\x83\x21\x38\x00\x12\xc6\xd3\x55\xf8\x41\x76\x68\x49\xe2\x2b\x77\x56\x4e\x06\x97\x15\xa7\xc2\xe8\x8b\x1a\x30\x99\x60\x46\x30\x57\xa0\x63\xf0\xcb\x22\x74\x5d\xb0\x91\x0f\x2f\xa0\x7c\x31\xf7\xdd\x47\x2b\xe6\xf5\xd1\xea\xd3\x0d\x2e\xfb\xc7\x36\xb8\xf0\x89\x8c\x97\xaa\x0d\xae\xc0\x12\x34\x75\xd9\xe0\x72\x22\x21\xa0\x76\xfa\xdb\x2f\xa2\x40\x08\xd4\x5f\xdd\xe0\x7e\x7c\xee\xb7\x25\xcb\xb6\xf9\x4f\x1e\xe4\x85\x8f\x0f\xce\xb6\x68\x99\x36\xf7\xc9\x83\x39\xf8\xb8\x7b\xb6\x19\x8b\xb7\xef\xef\x9e\x09\x1e\xd0\x1f\x0f\x16\x0c\x53\xb7\xf4\xcf\x1e\xe4\x3f\x0e\x67\x0c\xe3\xb3\x73\x08\x81\xbb\x73\xae\x20\xe8\xa2\xf9\xc9\x39\x81\x78\xe7\x9c\xc3\xd0\x34\x60\x7c\x76\x4e\x20\x7c\xdc\xff\xeb\x86\x28\xea\x9f\x88\x2f\xd1\x1f\xc7\x6b\x16\x6f\x68\x9f\x8d\xe7\xef\x3c\x8c\xd8\xac\x29\xdd\x1f\xff\x23\xcf\x15\x5c\x9c\x16\x96\xe0\x7e\xdc\xb3\xbf\x7b\xa4\xf0\x66\xf6\x9f\x3d\x4d\xb8\x36\x40\x69\x77\x91\x17\x7e\xfb\x45\xb7\x72\xcb\x7f\xd1\x22\xcd\x9d\x7f\x30\xcd\x87\xbf\x72\x6c\x78\xf2\xff\x66\xef\x23\x05\x6f\xca\xc3\x27\xad\x66\x73\x42\x06\x5a\xb0\x65\x36\x74\x8d\x3a\x77\x1b\xf4\x20\xe8\xce\x9b\xfb\xc5\xc6\x69\x4e\x5b\x93\x66\x72\xe2\x9a\x62\x7f\xee\x01\x9d\x74\x05\x49\x26\xd9\xd9\x8a\x09\x1b\x43\x6b\xe3\x38\xf5\xcd\x76\xd9\x1c\x2c\xc8\x92\x19\x32\x5b\x61\x20\x8c\xe6\x0a\xd9\xe6\xfd\x3d\x9d\x1c\x0b\x9a\x3a\x4f\xcd\x05\xb9\x5e\x4a\x60\xb9\x6c\x53\xc1\x6c\xd2\x27\x99\x10\x68\xe4\x6e\x5f\xf2\x26\xbf\x4e\x99\xb6\xb8\x5a\xcf\x6a\xe3\x82\x1b\xf2\xea\x7a\xa7\xaa\xed\x63\xa8\x91\x82\x18\x6d\xfb\x56\xd2\x4e\x37\xfd\x2c\x51\x9a\x80\x3f\xf6\xda\x2a\x50\x25\xa7\x39\x1a\x19\x1b\x93\x36\x55\x60\x0f\x8b\x44\x57\x49\x52\x5b\x0f\x85\x1e\xb0\xec\xf1\x20\xd8\x2f\x0e\xcd\x96\xbc\xa7\x64\x6a\xb9\x1d\xea\xad\xa6\x36\x69\xd4\x53\xa3\xbb\x5f\xef\x24\x81\x2b\x99\xa1\x7a\x90\x4e\xa5\x25\x8e\xeb\x7b\x39\xf4\x3a\xa3\x56\xec\xd6\x76\xb4\xd5\x60\x93\xd4\x8c\xea\xac\x9a\xb6\x8e\x7a\xdb\x27\x3b\x07\x71\x9a\xe5\x9b\x55\x7c\x9a\x4f\x3c\x8e\x8e\xc0\x2e\x5f\x79\xed\x8d\x36\xdd\xaa\x14\xa9\x1d\x15\x67\xb4\x6f\x90\x5b\xb1\xbe\x51\xe9\xf1\xe1\xe4\x99\x31\x68\x6d\xf7\x6e\xa4\x9c\x62\x4b\x5b\xcb\xe4\x62\x77\xdc\x91\x6c\x27\x1a\x9d\xfa\xfd\x9d\x37\xf2\xac\xbd\x30\x5d\xcc\xdc\xe9\x70\xb2\xd2\x86\x9b\xd6\xe4\x38\xd0\xec\x64\xd3\x38\x79\x05\x1b\x9d\xb7\x7d\xfb\xa0\x6f\x7a\x54\x33\x9f\x9a\x3e\x50\x26\x65\x39\x4f\xc5\x75\x63\x38\x97\xf9\x45\x53\x1d\x14\xb9\x52\xaa\xf1\x76\xd5\xdd\x0e\x87\xfe\x50\xf5\x27\xa3\x3e\xad\x0e\x7a\xd3\x5e\x8d\x93\xf7\xc7\x2d\x98\x09\x8d\x56\xeb\xdc\x3b\xef\x39\xbe\x1d\x2e\x76\x93\x95\xbf\xd9\x1f\x1a\x51\x7d\xd5\xd2\xa3\xb0\xb9\xdc\x18\xaa\x2a\xb3\xe6\x30\xac\xf3\x34\xdb\x9e\xa4\x4a\x7d\xd5\x75\xec\x6d\xaf\xe9\x9c\xf6\x51\xc3\x3d\xcf\x5a\xab\x3c\x64\x97\xf1\xc4\x0a\x94\x80\x5e\x16\xeb\x49\xba\xee\x15\x2d\xe0\xf2\x46\xcd\x39\xf9\x13\x6e\xe7\xcc\xbc\xe6\xa2\x99\x51\x85\xd9\xb5\x84\x6c\xd0\x9c\xd5\xc2\x66\x9b\xd6\x1a\xaa\xd7\x1b\x8c\xba\xdd\x55\x37\x91\x2c\x4a\x69\x36\x55\x79\xb0\x48\x8a\xe9\xd1\x70\x97\x72\x39\xef\x7b\xc1\xa2\x18\x09\x5c\x2f\xe0\x97\x2d\xa6\x9e\x0b\x5e\x30\xd2\x76\xb5\x93\x29\x2c\x5a\xfd\xe5\x8c\xac\x8f\x7b\x2d\xa0\x93\x4d\x36\x73\xe6\x49\x93\x95\x7a\x3c\x35\xe2\xf6\x86\x15\x0d\x0f\x51\xe1\x1d\x8f\x9b\xbe\x26\x3a\x6e\x67\x2d\xb3\xe2\x42\x1a\xcc\x69\x79\xe2\x94\xd3\x7c\x3e\x77\x9b\x0c\xa5\x4f\x3c\x6d\xd6\xd6\xd8\x52\x1d\xf4\x86\xad\xa8\xa6\x1c\x48\xda\xe8\x64\x6c\x63\xe3\x17\x65\xcb\xa6\x67\x7c\xbd\x53\x14\xc9\xa0\x20\xb5\x5c\xd1\xa7\x5c\x03\xec\x05\x17\x6c\x26\x6c\xbf\xc3\xc8\x81\x5d\x93\x8d\x6d\xd9\xd4\xb7\xe3\x5c\x6a\x74\xb3\xf3\x44\x01\xbe\xd4\xd4\xb3\xcd\x68\x97\x0b\x6c\x4e\x9a\xcc\x48\x9a\x0e\xc6\x73\x25\x49\x9b\x45\xbb\xbb\x1a\x8a\x07\xba\xdc\x0b\xeb\xe1\x66\x9a\x4a\xbd\x64\x9a\x33\x4b\x56\xae\xcb\xca\xac\x3d\xe5\xad\x09\x45\x0e\x27\x3f\xf2\x47\x96\x27\x3f\x3d\xfd\xcd\x40\xc2\xbf\xfd\xab\x85\x87\x56\xb3\xb9\x18\x2f\xd7\xe6\x78\x43\x1e\xad\xd5\xb6\x1b\x79\x9b\xad\x37\xdb\xf4\x37\x6e\xcf\xe0\x9b\xba\x79\xec\x8c\x5c\xc7\xdb\x45\x4c\x46\x16\x1d\x70\xe6\xeb\x54\x4f\x76\x47\xe5\xa0\xab\xba\xa7\x88\xdd\xf7\xda\x7b\x20\xcf\xe6\xf2\xa9\x58\xb5\xa8\x41\x1c\x73\x66\xc7\x90\xf2\xd6\xe2\xbc\x29\x3c\x53\x8b\x0e\xc1\xa1\x26\x4a\x9c\x74\x3a\xeb\xe7\x76\x36\x34\x4e\xbc\x34\x9e\xcf\x68\xbe\x39\x0f\x26\xd9\x4c\x4a\xd8\x4e\x49\x9e\x72\x61\xb0\x12\x76\xcb\x5a\xe6\x72\xe5\x79\x69\x68\x9b\xf1\x9a\xac\xd5\xba\x99\x74\x64\x87\x72\x5e\x6b\x2c\xa7\x7c\x56\x5f\x2c\xe6\x87\x41\x2f\x55\x8c\xe9\x79\xb7\x1d\x6d\x07\xe2\x4a\xda\xaa\xfd\x53\x8d\x5c\x2b\x3a\x6b\x71\xe4\xbe\xc3\x75\x43\xca\x8f\xbb\x9b\x55\x7b\xa1\x35\xa8\xcd\x7c\x1b\xd6\x1b\x72\xb3\x1f\x2d\xa7\x8c\xca\xf0\x91\x12\x09\x43\x3d\x75\xfc\x6d\xa1\x1f\x14\xde\x9b\xf4\x47\xeb\xd6\xc0\xe8\x2f\x96\x76\x7d\x5f\x97\xa3\x89\xeb\x2b\xdc\xe9\x34\x50\x62\xb2\x93\xcc\x72\xe6\x00\x7a\xce\x66\xc5\x9c\xa9\x13\xd5\x5f\x9f\xf7\x8d\x4d\x4f\x9b\x6e\xfd\x5d\x72\xa4\x19\xad\xb3\x9a\x9f\x55\x4f\x0b\xe4\xb2\xcc\x72\x6a\x24\x2d\x36\xa6\xcd\x8d\xe5\xe4\xe0\xc7\x71\xdd\x1e\x2c\xec\x23\x1b\xc9\x6a\x33\x39\x6c\xeb\x7d\x63\x71\x1a\xb4\xa6\x8d\x4e\x33\xa6\x14\x67\xc5\xa9\x11\x3b\x94\x86\xdd\x21\x30\x5b\xd4\x7a\x9d\x2e\x5b\xa3\x45\x39\xee\xcd\xcf\x51\x6d\x55\x97\x87\x8a\x67\xee\x62\x31\x73\x3a\xed\x36\x63\x50\x4a\xd8\x63\x8f\xdd\xa9\xcd\x1a\xa3\x46\x5d\x5b\x71\xfd\xdd\x46\x3c\xed\xb7\xaa\x40\x9f\xe2\x9e\x34\x31\x5a\x67\x4e\x5f\x1e\x3a\x8b\x5e\xbb\xb3\x55\xe9\x4d\x36\x0c\xfa\x1e\xc5\x6f\x1a\xa5\xb7\x6c\xe9\x6c\x4a\xe6\xcd\xfe\x60\x2e\xdb\x20\x66\x2d\x73\xd4\xe6\x83\x81\x07\xce\x53\xbe\x68\xc6\xe6\xa2\x58\xd7\x72\x55\xc9\xf6\x8d\x73\x27\xea\x0b\x71\x66\x0c\x78\xad\x54\x83\xb6\xb6\xcb\x33\xeb\xc4\x8e\x7d\xaf\x8c\xba\xfb\xd6\x74\x17\x2c\x9a\xf2\xcc\xf2\xeb\x74\xb2\x9e\x4c\x67\xf6\x6e\xd1\x98\x4b\x63\x7f\x15\x07\x2b\x1a\x78\xf3\xf6\xb9\x21\x97\xcd\xfd\xc2\x3b\x8d\xa7\x87\xb5\x6b\xd1\x4b\xf6\xdc\x37\xce\xba\x19\x94\xba\xb3\x8f\x7b\x94\xd1\x1e\x1d\x65\x7e\x43\x0f\xe6\x8d\xb4\x1f\x79\x5c\x27\x1d\xf6\x85\x21\x33\x18\xd6\x8e\xc5\x46\x5b\xe9\xa7\x8d\x1d\xa9\xea\xfe\x6c\x9e\x0c\xab\xe0\xfd\x64\xb3\xd2\xb6\x6e\x20\x8e\x3b\x9d\x36\x73\xb6\xed\x18\x2c\x8a\xde\xac\x73\x96\xf2\x7c\xbf\x10\xc7\x91\xa9\x1b\x93\xcd\x66\x33\xe3\xfc\xd3\x66\x7f\x9a\xef\xdb\xe6\x52\x99\x98\x4b\xd0\x4b\xc1\x61\xec\x6c\x14\xbe\xd7\x3d\x76\x9b\x82\x93\xae\x97\x96\xdd\x75\xbb\xc7\x01\xc5\xed\x05\xb3\x18\xe8\xd6\x20\x70\x45\x41\x03\xe2\xd1\xee\x0e\xb4\xe5\xa6\x8c\x93\xa4\xa7\x3a\x3b\x8b\x1e\x26\x35\x90\x9d\x37\x6b\x79\x18\x2a\x61\xc2\x9c\xa7\x6e\x67\xc7\x08\xcb\xbc\xa4\x8b\x78\xdd\xc9\x86\xb2\xc9\x91\xc5\x64\x23\x2b\xfc\x6a\x70\x9c\xd3\x8d\x22\x5a\xfe\x50\x80\x08\xfe\x66\x2f\x22\x79\xfe\x4d\x8d\xdd\xea\xcf\x13\x9d\xdc\x9a\xc3\xac\xe8\x0c\xb4\xa9\xb4\x79\x28\xbb\xb3\x32\x5c\xb4\x7a\xe9\x6c\x34\x73\x87\x45\x43\x0b\xbc\xcd\xb6\xa9\x30\xaa\xd3\xdd\x1b\xc7\x53\x34\x24\xbd\xc6\xd6\x1a\x6f\xbd\x4d\x5b\xa1\xb5\xb6\x52\xf3\xa8\x16\xd7\x1f\x34\xdc\x93\xbf\xd4\xb4\xbd\xdc\xa7\xcb\xbd\x21\x67\xb5\xd5\xd9\x54\x8f\xc2\x79\x7f\x8a\x98\xd5\x56\x65\xe3\xa3\x18\xac\xed\xc0\xb2\x36\x8c\x28\x72\x47\x87\x17\x92\x68\xdc\x72\xb9\x30\x37\x78\x3a\x90\xdc\x5d\x34\xad\x71\xea\x20\x16\x06\xc9\x7e\x63\x33\x02\x75\x58\x66\x46\x54\x5b\x66\x8d\x45\x2b\xd6\x77\xb5\x5d\x7b\x5a\xeb\xe9\xab\x50\xe0\x47\xe5\x44\xb4\xc6\x45\xba\x95\xe7\x13\x5d\x9c\x92\xae\x16\x6e\x9d\xee\xd0\xd9\x49\xdd\x83\x75\xac\xb7\x1a\x05\xe8\x67\xd2\x68\x50\x0f\x87\xab\x46\x4a\xb3\xeb\x62\xdf\x26\x27\xfd\xcd\xa2\xe9\xb5\x77\x4b\x79\x3c\x89\x6c\x32\x39\x50\x82\xc8\xc4\x33\xb7\x39\x67\x16\xea\x24\x12\x4f\x67\xca\x9b\x71\x2d\x4d\x1e\x06\x49\x67\xd2\xa1\x95\xe8\xb0\xa9\x29\x33\x75\x76\xe6\xa7\x67\xcb\x58\xf9\xa1\x22\x95\xc1\x82\x15\xd4\xcd\xce\x64\x47\x5c\x7d\x7d\x50\xe6\x6d\xb6\x35\x60\x86\xf1\xbc\xb9\x8f\xcd\x1e\x97\x14\x94\x1c\x15\xea\x74\xa0\xbb\x0b\x3b\xe6\x44\x67\x3e\xd2\x14\x72\xd1\x09\x86\x93\x71\x97\xdf\x04\x79\x7f\x35\x5d\x83\x73\x73\xd6\x59\xf4\xc8\xa8\x9e\xd2\x61\x30\xd6\x6a\x03\xa7\xa0\xb6\xdd\x01\x93\x6d\xcb\x76\xd4\x2b\x4a\xe7\x3c\x19\xd6\xe9\xdd\xb0\xec\x75\xb7\x6b\xc1\xab\x53\x7e\x3c\x8e\x06\x02\xb5\x68\x07\xe3\xb5\x78\x6e\x2c\x6a\x49\x5b\x1c\x2a\xcb\x53\xa7\x30\xbd\x06\x17\xf4\xd3\xf1\xa2\xb5\x18\x92\x4e\x9e\xa9\xaa\xcd\x48\x69\xeb\xbc\x3c\x68\x43\x66\x93\x34\xf8\xf9\xae\xae\x1d\x0f\xee\xda\x1d\xca\x60\x3e\x89\x0e\x7e\xb4\x14\x14\xad\x16\xef\xb6\x07\xd0\x4a\xd7\x8b\x86\x16\xb4\x68\x69\xc7\xab\xf9\xc6\xb5\x19\xaf\x3b\x83\x9b\xc9\x56\x2e\x29\x5b\x2b\x8f\x8e\xee\xf4\x7c\x1e\xdb\xa3\x76\x8d\x71\x63\x59\x5a\x48\x8b\xd2\x8b\x46\xfe\xbc\x27\xc4\x2d\x6b\xde\x98\xcc\xf8\x69\xfb\xdc\xb5\xf4\xd2\xae\x45\x67\x2e\x9e\x9d\x57\x59\x30\x5b\x81\xe6\x48\x8a\xdd\x7c\x42\x51\xa9\x5f\x9f\x66\xa4\x78\x98\x32\x4a\xb4\x32\xd7\xba\x67\x9c\x17\xde\xfc\x6c\x72\xb4\x52\xcb\x4c\x35\x28\xe7\x75\xc0\x06\x27\x90\x0c\xe4\xfe\xd2\x98\xc6\x4d\x79\xbe\x4b\xd2\x63\xd3\xb7\x2c\xb2\xb3\x6e\x07\x61\x6b\x5a\xd6\x47\x6d\x85\xa1\x1a\x64\xd8\x54\x76\x43\x27\x15\x1a\x4a\x9c\x6e\x82\xb0\xd3\x66\x36\x63\xcb\xa9\x37\xf2\x4e\x2a\x45\x1b\x3b\x10\xc3\xb6\x64\xf6\x34\x6e\xcd\xf6\x45\x59\x9e\x9c\x27\x6b\xb6\x3f\x1b\x32\x85\xf1\x43\x5f\x2a\x2c\xff\x6e\xb9\x6c\x9e\x5e\x6b\x8c\xfa\x97\xba\x28\xfa\x40\x08\xb8\x0d\xb5\x8d\xb3\x23\x0d\xe4\x62\x55\xb8\x9b\xd8\x9e\x29\x2d\xb7\xb6\xcf\xf3\xa9\x29\x0e\xa9\x8e\xcd\x76\xc9\xd3\xca\xb4\xc9\x09\xe0\xc4\x16\x35\x89\x26\xb5\xc6\x32\x6d\xf5\x35\x75\x36\x89\x33\xd2\x8c\x83\xfc\x9c\xcd\x47\xe7\xf3\xbe\xe4\x0d\x2b\x1b\xc5\x2b\x63\xbb\xcd\xf5\x11\x33\x18\x71\x1c\x60\x67\xa7\x73\x73\xc1\x24\x9c\x40\x32\xed\x78\xe5\xfb\x03\x32\x1b\xb3\xa9\xca\xcc\xb5\x64\x3a\x5a\x1f\x67\x11\x39\x5b\xf5\xf2\xb5\x00\x16\x47\x91\x6a\xd8\xae\x9f\x90\x73\x76\x61\xae\x5a\xf2\xd2\x36\xc3\x20\x9d\x2f\xb2\xdc\x1c\x33\xdc\x68\x51\x4e\xfa\xcb\xb0\xe7\xac\x95\xfa\xdc\xd8\x49\x9e\x21\xa7\x73\x4b\xd5\x4e\xc2\x8e\xa4\x38\xfa\x30\x10\xc1\x62\x57\xac\xc0\xa4\xb7\x6e\xba\x83\x16\x75\xd8\x84\x43\x89\xb2\xcd\x30\x37\x23\x67\x13\xe4\xbd\xf1\x82\x22\x97\x75\x39\x56\x58\xd7\x50\x92\xd5\xd4\x28\xbd\xbd\x5d\x07\x42\x9a\x9c\x9d\x95\xa0\x4b\x53\x17\xe4\xcd\xfc\xa4\xf8\x5d\x36\x5b\x96\x99\x56\x9f\x35\x9b\x59\xb0\x72\xa9\x53\xba\x18\x14\x71\x11\xae\x76\x07\xd9\x37\x4e\x91\xe3\x75\x4c\x50\x78\x93\xb2\x71\x14\x05\xaf\x4b\xd6\xd2\x5e\x66\xf3\xb5\xe1\x3a\x75\x62\x53\x68\xad\x1a\x83\x3a\x47\xf5\xf3\xfd\x66\xd0\x1e\xe8\xaa\xb9\x75\x54\xdf\xde\xd5\xfa\x52\x9f\xad\xb5\xc2\xd6\x84\x3e\x09\xab\x30\xeb\xa6\x1c\x25\xeb\x81\xd7\x2e\xd4\xae\x9a\xd5\xf6\xb5\x66\x7e\xce\x67\xc3\x6e\xe7\x6c\x7a\x8e\xd9\x23\xe5\x60\x3d\x99\xba\x5e\x27\xe7\xc6\xa3\x59\xb1\x09\xda\x35\xe3\x30\x5e\x46\x54\xe7\xa0\x9c\x76\xe2\x71\xde\xa7\xf3\x10\x74\x6c\xad\xd6\x0b\xcc\xee\x3e\xcf\xb6\x24\x6b\x8f\xc6\xeb\x05\xb3\x1a\x2b\x71\xcb\x1a\xae\x96\xe5\xa2\x9f\x94\x0d\xaf\xdb\x1e\x0c\xd9\x73\xda\x91\x44\xa7\x0c\x98\x46\xd7\x18\xcd\x8b\x79\x6d\xdd\x31\xd7\x89\x39\x99\x74\xe4\x6d\x94\x35\xc5\x7d\x7d\x1c\xcf\x0e\xe3\x61\x27\xab\x8f\x12\x56\xec\x2c\x02\x75\x64\xac\xa7\xbd\xb9\x64\xae\x86\x83\xf6\xa6\xd7\xd2\x4b\x09\xc4\x9d\x91\x9c\x6b\xe5\x7e\xa6\x75\xe7\x4e\x4d\x2f\x2c\xdb\x74\x93\xcc\x52\xa6\xf3\xc1\xac\x28\x93\x56\xc3\xe9\x8a\x62\x93\xe2\xf8\x4e\x59\x63\x65\x97\x36\xd6\x93\xad\xca\x4c\xe1\x86\x5a\x5d\x58\x82\x7d\x58\xaf\x5a\x43\xfe\x47\xae\x97\x67\xef\x6f\x56\x4f\x30\x90\x5e\xf6\xd3\x7b\x2a\xcb\x29\x4a\x5e\xb8\x46\x6d\xb0\xe1\xcd\x51\xe0\x58\xad\x9e\x03\x5a\xd1\x72\x19\x2f\x56\x7e\xab\x41\xa5\x74\xb7\xd5\x02\xbb\x53\x5d\x77\xfb\x3b\xb6\x3e\x3b\x6d\xcc\xd4\x18\x6f\x8c\x66\x30\x09\xba\xca\x81\x72\xd2\xe6\xb4\xbb\xf4\x4a\x76\x1e\x2b\xc2\xb2\x75\x6e\x81\x4e\xc4\xed\x2c\x5a\x63\x33\x77\x74\x18\xba\x7e\xcc\x0d\xce\xec\xf9\x68\x9e\xcf\x31\x55\xc4\xd3\x79\x43\xb4\xc7\xc9\x9e\x22\xe7\x0d\xbe\x66\x2b\xd9\xc6\x33\xd4\x8e\x24\xcc\x41\xdf\xa0\xf3\x89\x62\xa4\xb5\xa4\xc3\x58\x0b\xf9\xb4\x3c\x87\x21\x65\x87\x40\x99\x0e\xc4\x66\xcd\x1b\x99\x39\x67\x64\xcc\x3a\xd8\xb6\xf9\x72\xe9\x0f\x77\x7c\x1a\xf9\x0b\xdd\x59\xce\x33\xea\xc0\xb5\xda\xd9\x9a\xcf\xd7\x87\x06\xbf\xdc\xfb\xf3\x66\xad\x2f\x8f\xc8\xd1\x48\xe9\xcc\xba\x93\xf1\x74\x12\xa7\xeb\x46\x6d\xbf\x6f\x9e\xe9\xa6\x2a\x53\x65\x9a\xe5\x22\x9b\xa9\xe7\xf2\x68\xa4\xfa\xaa\x5e\x7a\xa9\xdc\xb6\x6b\x13\x79\x46\x37\x1a\xca\x74\xaa\x0e\x7a\x83\xe0\xd4\xa8\x79\x62\x83\xdd\x99\x6a\x23\x20\xcf\x03\x61\x34\xea\xb7\xda\x71\x66\x8c\x78\xb2\x3e\x8f\x7b\x54\x69\x4d\xea\xd4\xa6\x16\xd8\xfd\xc9\x71\xbb\x6d\x53\xbb\x89\x63\x4d\xf5\x95\xb8\x36\xa3\x20\xd2\x53\x49\x1d\x8a\xa9\x61\xd4\x16\xe3\xce\xb0\x64\x95\xe2\x20\x76\xfd\x5d\x94\x75\xbb\x93\x66\xc0\x49\xe4\x34\x9a\x95\x03\xd0\xe8\xef\xd7\xfd\xed\xb0\x1e\x08\xfb\xee\xd2\x29\x07\x7c\xe1\xc8\xe1\xcc\x99\xf6\xa5\xfc\x30\xb1\x3b\x63\x6f\xd0\x52\x3a\x87\xb2\xb5\x4c\xd5\xa9\xd4\x08\xa8\x88\xdd\x9c\x23\x59\x9e\x25\xb3\x5d\xc3\xf2\x27\xf6\x74\xac\x83\xa5\xc1\x1e\x42\xaa\xb9\xe1\x54\x7a\x25\xb5\x9b\x5a\x5d\x35\x4e\x13\xa7\xd5\x89\xdb\xfa\x7e\xd0\x55\x7a\xbc\x64\xd5\x8a\x5d\x4f\x5c\xae\x0f\x53\xa7\xef\x99\x54\x22\xd8\xd9\xc4\x3c\xed\xa7\xa9\x34\x3b\xc8\xf4\xde\x91\x03\xc0\xce\x66\xdd\x89\x2b\x1d\xdd\xa3\xda\x1e\x0f\xc2\x7e\x2f\x25\xb9\xfe\xe1\xa8\x82\x13\x35\xa4\xa6\x8d\xd4\x3b\x7b\x4e\xa4\x68\xea\xa1\x6e\x76\xa2\x81\x57\xe6\x89\x5f\x4f\x3b\xcb\x13\x28\x62\x57\x61\xeb\x0d\xab\x88\x0e\xa7\x76\xbf\xaf\x14\xb2\x93\x8d\x4a\xb1\x77\xb4\x37\xc7\x7d\x8d\x73\x22\xbf\xdd\xd6\xda\xdb\xc2\x00\x69\xb7\x1d\x29\x67\x46\x1e\x8d\xb7\xb3\xa5\xaa\x75\x9c\x65\x51\x9a\x51\x4f\x19\x80\x0e\xab\xe8\x93\x91\x72\x74\xdc\x3a\xb3\x89\x47\x0a\xcb\x76\xec\xa8\xe3\x84\x47\xd6\x12\x66\x11\x75\x94\x3d\x2a\xcd\x3a\x6a\x8f\x91\x8f\xa6\x58\x97\xf4\xb8\x73\xe4\xf3\x71\x34\x3b\x4a\xf3\x4c\xf1\xf9\x6c\x71\x8c\x5a\x5e\x77\x33\x72\x8e\x54\x0d\x70\xe2\xa0\x1f\x8c\x4e\x51\x90\x95\x0a\x33\xf1\x48\x66\x30\x9f\x0a\x9e\xd8\xa7\x9a\x4a\x1b\xb4\x3b\x23\x4e\x69\x32\x6b\x56\xc9\x87\x9a\xbb\xf5\x7b\xa3\xa2\xb9\x1f\xc9\xf3\xdc\x1c\x1b\x34\x49\xba\x27\x26\x58\xf7\x38\xbf\xd5\xd3\x5a\x62\x5f\xd4\x67\x99\x49\x6d\xda\x76\x38\xea\xe9\x83\xb6\x75\xa2\xc1\x89\x37\x50\xbd\xa2\x91\xdf\x1d\x2b\xbd\x73\x22\x18\xea\x8f\xc1\x09\x3d\x32\x4b\xec\x09\x1d\x5f\x3e\xfe\xcc\xb0\x8c\xc0\xd8\x5f\xec\x28\xcc\x70\x5b\x0b\x3c\xbf\x7c\x7c\xe8\x58\x7e\x6e\x65\x9e\xa1\x61\x43\xeb\x68\x3d\xfc\x8a\xbd\x34\xfc\x8a\xc9\x89\xa7\xf9\xbf\x62\xa9\x16\xa6\x78\x6a\x25\xde\x65\x2a\x62\x00\xd8\xf8\xf4\xc5\xf7\x42\x0b\x77\x2d\xcf\x71\xb3\x47\x40\xb0\xcc\x97\x40\x4b\x1c\x2f\x7c\xa4\xbe\x14\x51\x62\xe2\x7a\x62\x69\xfb\x47\xf4\x1d\xd7\x7c\xff\x0b\x5e\x58\xfa\xde\xcb\xf0\xcc\x3a\x55\x54\x70\xcd\xdc\x1d\xd3\xec\x11\x50\xd4\x3f\xbe\xe0\x41\xfa\x59\xcf\x75\x9e\x16\xe3\xae\xe7\xb8\x3e\x64\x58\x9d\xc9\x3e\x66\x89\x16\xa6\xb1\x96\x58\x61\xf6\xac\xbd\x68\x0a\x80\x60\xe9\xcc\x17\x44\xce\xb4\x8c\x28\xd1\x32\x2f\x0a\x1f\xc3\x28\xb4\x9e\xb5\x47\x37\xca\xad\xe4\x65\x2c\x45\xe9\x94\x25\x7d\x18\x7b\x0c\x4d\x2b\x81\x0a\x3e\x6b\x8f\x9a\x91\x79\xb9\xf5\xab\xf6\x98\x7b\xa9\x97\x59\xe6\xbb\xb9\xcf\x69\x96\x44\xa1\x83\x3d\x21\xf3\x14\x95\x3d\x04\x8a\x7a\xce\x34\xdd\xb7\xb0\x27\x3d\x4a\x4c\x2b\x81\x02\xfb\x5a\x9c\x42\xe7\x54\x17\x5f\x2e\x1d\x69\xac\x19\x5e\xe8\x3c\x52\x5f\x02\xed\x54\x9d\xda\x56\x8a\xbf\x5e\x56\xa4\x1e\x7d\x2d\xcd\x70\xc3\xf5\x7c\xf3\x85\xaa\x1e\x65\x59\x14\xe0\xbe\x65\x67\x78\xa2\x99\xde\x31\x7d\x64\xe2\xd3\x97\xb7\xbd\x09\xb2\xd8\x6b\xf7\x73\x96\x3c\xda\x5e\xf2\x42\x2c\x7b\xa5\x97\x45\xf1\x23\x05\xfb\xc3\xcc\xc5\x23\x1b\xcf\xca\xd8\xfa\xa7\x95\x5b\xe1\xbf\xde\x2c\x35\x17\x03\xd8\x82\x2d\xda\xda\xf3\xbb\xf9\x20\x3e\x61\x69\xe4\x7b\x26\xf6\xb3\x29\x99\xba\x45\x7f\x89\x35\xd3\x84\x2a\x12\x3c\x67\x05\x5f\x72\x2b\x81\x11\xe6\xe3\x9a\xef\x39\xe1\x63\x16\xc5\xcf\x3f\xc7\x9a\x03\x63\x49\x33\xa1\x6b\x50\x3b\xee\x65\x56\x90\x3e\x1a\x56\x98\x59\xc9\x4d\x84\x3f\xfe\x4c\xe9\x8c\xc6\x31\x6f\x75\x7c\x64\x5f\x99\xf2\x92\xc1\x1a\xe6\x97\xab\x8c\xb6\xfd\xc5\xf4\xd2\xd8\xd7\xca\x47\xdb\xb7\x4e\xb7\x51\x4c\x00\xda\x0a\xbe\xdc\xfa\x8d\xa3\xa8\x2f\x30\xf4\x3c\xbb\xc4\x61\x16\x59\x61\xf6\x08\x1d\x64\xe1\xba\x95\x15\x96\x15\xbe\xe8\x42\x61\xc0\x0a\xde\x0a\xfe\x1a\x81\x95\x08\xef\x7a\x2f\x81\xf4\x32\x48\xd2\x4c\xd6\xd4\xdf\x0f\x7a\x1b\x9e\xb6\x6d\xbf\x19\x80\xfb\x91\x13\x61\x4f\x97\xac\xa3\x09\x1a\x1a\xf4\x92\x77\x84\x60\x05\xd8\xeb\x37\xea\x12\x40\x02\x01\xb8\x77\x92\xe2\x81\x15\x1e\xef\xda\xf9\x8d\xa5\xae\x74\xa1\xd7\x30\xea\x0e\x05\xd3\xcb\xb1\xa7\x6b\xd6\x63\x04\x7f\x97\x8d\xe9\xe5\x6f\x22\xf7\x65\x3c\xfc\xef\x93\x39\x69\x0e\xf3\xc9\xf3\xfd\xab\x29\xbf\xbc\xe0\x8c\xf8\xa2\x30\x0a\x36\x02\xd0\xf7\xb5\x4b\x73\xe7\x6a\xcb\x8a\x10\x34\x25\x01\xbb\x90\xc6\x78\xa8\x25\x49\x54\x60\x4f\x57\x8d\x11\x3a\xfc\x7c\xf1\xf9\x35\x9e\xef\xc4\xf2\x25\xec\x2e\xd9\x04\x71\xf0\xa2\x10\x0a\x87\xcb\xfc\x97\x50\xfe\x98\x33\x96\x69\x53\x36\xfb\x2e\x7a\x3f\x65\x93\x45\xf1\x67\xc9\x0d\xbb\xde\x67\xf6\x6b\xa6\xc1\x08\x80\x12\x11\x30\x83\x71\xcf\x88\xc2\x5f\x5f\x2f\x7f\xfb\x5f\xd8\xd3\x05\x5d\xaa\xe0\x20\xc2\x08\xfd\x78\x08\xa1\x35\xf6\x54\xb8\x5e\x66\x21\x60\xb2\x1e\xc3\xa8\x48\xb4\xf8\xb2\xe5\x74\xb5\xd4\x7d\x89\x4d\xc1\x16\x59\x09\xbc\x59\x50\x82\x28\x8c\xd0\xb4\xe7\xff\x0a\x2c\xd3\xd3\xb0\x28\xf4\x4b\x2c\x35\x12\xcb\x0a\x31\x2d\x34\xb1\x7f\xbe\x62\x1c\x47\x51\xf1\xe9\x5f\xd8\xd3\x77\x7c\xe2\x85\x08\x82\x6f\x46\x14\x9e\x69\xbd\xf3\xd9\x95\x55\x9c\x78\xd0\x71\x6f\xa1\xe4\xae\x77\x2f\xbd\xbf\xbe\xea\xf4\xeb\x9b\x95\x92\xa2\xa8\x3b\x9e\xfc\xcc\x61\xb7\xa3\xef\xc5\x0d\xec\xd7\xee\xae\x1e\xd4\xf7\x96\x9d\xff\xed\x26\x96\xfd\x7f\x1e\x35\x3b\xab\xe0\xa0\xc2\xa2\x07\xec\x9f\x0f\x98\x96\x65\xc9\x3f\x61\xf7\xbf\xb0\x87\x7f\x3d\x3c\x67\x09\xf6\x84\x94\xae\xd6\x5a\x2f\x4c\x3d\xd3\x7a\xd4\xf2\xc8\x33\xff\x28\x92\xdf\xae\xa3\x9f\xa3\x39\xd4\xe4\xf9\xbf\xe0\x4a\x9d\x7b\x56\x11\x47\x49\x76\x0d\x23\xd3\xca\x3d\xe3\xf2\x23\xc7\x67\xc2\xc4\x21\x7c\xbc\x1a\x1f\xde\x3d\x13\xf0\x3b\x0e\x63\x09\x7b\x42\x97\xb6\x1f\x15\x8f\x55\x6c\xa1\xfb\xd4\x4d\xbc\x70\x8f\x83\x4b\x77\x75\xfb\x08\x9e\x89\xc0\xc7\xb5\x63\x16\x5d\x91\x03\xe5\xc3\x23\x6c\x79\x26\xd0\xba\x88\x27\x56\x1a\x47\x61\x8a\xb0\xf5\xca\x53\xf7\x23\x63\x7f\xb3\x84\x7e\x81\x50\x00\x59\xe2\x27\x34\xf7\x65\x5b\xf1\xd2\x9e\x1a\x49\xe4\xfb\x30\x79\xb2\xe8\x68\xb8\xcf\xb8\x85\xfd\xf4\x95\x44\x2f\x21\xfc\xf6\xd3\xd7\xc0\xca\x34\xec\xfa\xbe\xc3\xc3\x31\xb3\x71\xf1\x01\x23\xaf\x1d\xa1\x16\x58\xdf\x1e\x4c\x2b\x35\x12\x2f\x86\x9e\x7c\xc0\x2e\x1e\xfb\xf6\x20\x63\xa6\x97\x58\x46\x16\x25\x25\x16\xd9\x98\xed\xf9\x56\x8a\xb9\x51\x0a\x63\x21\x0a\xb1\xcc\xb5\x30\xd3\x4b\xb3\xc4\xd3\x8f\x99\x65\xfe\x8a\x99\x16\xc4\xe2\x44\xf3\xbd\xb3\x65\x62\x85\xa5\x63\xc7\xd4\x0b\x1d\xac\x3b\x6e\xcd\x1e\xae\x0c\xe3\x24\x8a\xad\x24\x2b\xbf\x3d\x44\xce\x63\xe6\x65\xbe\x75\xc3\xb1\x85\x58\x44\xe1\x77\xa6\xdc\x17\xf5\xe9\x09\x23\xc6\x5a\xe6\x62\xcf\xcf\x9f\x70\x2a\xe3\x5b\x46\x85\xa5\xc3\x98\xbe\x3f\x16\x3d\x7f\xde\x0c\x76\xb3\x2c\x4e\x1f\x49\xd2\xd1\x32\xab\xd0\x4a\x94\x7c\x84\x17\x91\xf0\x93\x9c\x04\x33\xc5\xda\xc8\x96\x14\x38\x1a\x3f\x34\xe7\xd1\x59\xde\x1e\xcb\xb6\xca\x4c\xc0\x7a\x97\xaa\x59\xbe\xa6\xc5\x75\xeb\xd4\xeb\x88\xd1\x78\x77\x78\x78\x6b\xf7\xac\xf0\xb2\xcc\x4a\x3e\xd8\xe1\x9e\x3a\x6f\x67\xfc\x07\x3d\xf6\x96\xb1\xa1\x25\xe6\x0d\xc7\xf4\x18\x04\x5a\x52\xfe\xdb\xd7\x12\xc7\xfa\x77\x65\xb9\xfb\x13\xff\xf3\x56\x35\x12\x4b\xcb\xa2\xe4\x86\xe7\x7f\x41\xe2\x9f\x8c\x46\xf1\xf0\xfd\xa1\xff\x39\x15\xae\x30\x75\x1b\xb2\xe8\xb7\x22\x6e\xf1\xea\x57\xcc\x0b\xbd\xcc\xd3\x7c\x3c\x35\x34\xdf\xfa\x06\x08\x0a\x92\xf1\xbd\x70\x8f\x25\x96\xff\xed\x21\x75\xa3\x24\x33\x8e\x19\x06\x97\xce\x07\x0c\x02\xef\xb7\xdb\xb7\xa1\x4e\x68\x4d\xbd\x9e\xb2\x54\xe7\x29\x4d\xb9\x89\x4e\x55\x9a\x72\x57\xae\x47\xf0\xb2\xe5\xc8\xb2\xdc\x40\xf5\x59\xd0\x8f\x55\xbb\xf2\xb5\xff\xfa\x35\x91\xff\xca\x97\x1f\x89\x12\xc9\xf1\xdb\x09\x29\xfe\x25\x3a\xb2\xdc\x58\xec\x94\x23\x40\xf4\xf8\xc0\x9d\x8f\x6b\xe7\x64\x39\x26\xc3\xd8\x57\x48\xae\xa6\x4d\xfb\x7f\x82\x7e\x67\xe8\x75\x67\xfc\x6a\x77\x66\xc8\xa3\xde\xda\x90\x02\x0f\x56\x64\x2d\x8f\x81\x42\x1e\x93\xe9\x96\x14\x73\x65\x6b\x93\xed\x3c\xe8\x54\xf4\x41\x7d\xd8\x0d\xbe\x43\xbf\xa7\x8d\xc7\x76\x6d\x1f\x36\x77\x64\x9e\x2c\xf5\x0b\xbd\x5a\xb6\xcc\xc9\x84\x37\x27\xa4\x70\xa0\x56\x36\xa9\x16\xf4\x9a\x2c\xc5\xa1\x5f\xd1\xaf\x65\xf1\x5e\xa8\xe8\x17\x77\xe9\xd1\xc9\x72\xfd\x81\x1e\xba\xe7\x6b\xe1\x62\x5c\xe3\xb3\x56\x78\x43\xef\x96\x7e\x9b\x5f\xe7\x35\x2b\x58\x8c\xc9\x1b\xfb\x21\x7d\xef\xd2\xbb\xaf\xff\x3b\x79\xab\xfb\xf7\xf2\x22\x7f\xdc\xa7\xf7\x3b\xfa\xdf\xdc\xbf\x8f\x8f\x4a\xff\xbb\xf4\x72\x7d\xaa\x91\x1c\xea\x47\xfa\xdd\xd7\x1f\xd9\xf7\x8f\xeb\xcf\x1d\xe6\x93\x71\xcd\x0b\xf7\x3a\x19\xc5\x5c\x9b\xe4\xfb\xe6\x34\xff\xef\xe9\x9f\x1e\xfc\x59\xa5\x0f\xa9\x9e\x56\x3a\x49\x0d\xfc\x98\x94\x94\x9e\x66\x93\x7d\x38\x3f\xea\x65\x4d\x52\xa8\x31\xeb\xf1\xef\xea\x2f\x65\xad\x84\x0c\x7a\xcd\x1a\x29\xb4\xd3\x45\x4e\x4e\xcb\x20\x21\x29\x23\x3e\x90\x52\xa7\xaf\x7d\xb8\xaf\x9d\x92\x96\x5a\xc9\xf7\x1d\xfd\x91\x7e\x77\xe7\xff\x2e\x7d\x64\x9f\xbb\xf1\xda\xef\x5b\xd3\xbc\xc6\xa4\xbe\xfe\x67\xe8\x81\xb4\xb5\xae\xe4\x79\x4f\xef\xe6\x0b\xf6\x2f\x10\x7d\x72\x78\x0a\xec\xfb\xf4\x44\xa6\xbd\x25\x5f\xfd\x37\xfb\x9c\xdc\x5d\xfa\x80\x47\xf4\x91\xbf\x4a\x71\x19\x90\xe8\x1e\xd2\xd3\xc6\x7f\x82\xd4\xa7\xf4\x11\xbd\xcc\xf8\x43\xe3\xc9\x50\x94\xe5\xb1\x63\xcb\xb2\x52\x28\x85\x2c\x17\xf2\x00\x82\x72\x5d\x96\x1b\x08\x8a\x1d\xb9\xf9\xdd\x7b\x34\x7e\x2c\x8f\x65\x59\x61\x3b\xc5\x85\x9e\xfc\xed\x5b\xb5\x2b\x44\x5b\x91\xdf\x6e\x36\x20\x5f\xc9\xaa\xe9\xa7\xaf\x24\x7c\xa2\xf8\xed\xa7\xaf\xf0\x91\xe3\xb7\x9f\x30\xec\x2b\x7c\x8a\xf6\xcc\x6f\x0f\x37\x0f\x2e\x0f\xb0\xe3\x7e\x17\x3a\x01\x78\xc0\x0c\x5f\x4b\xd3\x6f\x0f\xe8\x09\x06\xb5\xfc\xf6\x3f\x43\x3d\x8d\xbf\x7c\x25\x4d\x2f\xff\xce\x6c\xf8\x28\x75\xa1\x7e\x19\x71\xa1\xf4\xf6\x19\xeb\xe1\xb7\xaf\xda\x65\xa5\xbb\x2e\xcf\x97\x65\xf9\x01\xcb\xe0\x26\x25\xfb\xf6\xf0\x6f\xdd\xd7\xc2\xfd\x43\xb5\x48\x86\x51\x14\x5b\xa1\x95\x60\x61\x94\x58\xb6\x95\x24\x50\x09\x59\x8f\x8e\x19\xda\x06\x7d\x25\xb5\xdf\x6e\x44\xfb\xef\xb1\xfe\xd9\x0b\xd3\x4c\xf3\xfd\x3f\x23\x42\xb7\x9a\xf2\x67\x84\xa8\x9e\x42\x7f\xa0\x05\x7e\x10\xdf\xbf\xa0\xfe\x5d\x09\xae\xd7\x18\xf6\x81\xa3\xe3\x65\xee\x51\x27\x8c\x28\xa8\x76\x61\xa6\x97\xe0\x5e\x68\x5a\x27\xdc\xcd\x02\x9f\xf4\xd2\xf4\x68\xa5\xe4\x9f\x11\xe4\x85\x17\x86\x7d\x4d\x73\xe7\xf2\x66\xf8\xc3\xe7\x6f\x86\x3f\xbc\xbc\x19\xfe\x40\x61\x14\x06\x44\x82\xc5\x68\xf0\xf0\xdb\x57\xc3\x4b\x0c\xdf\xc2\x8c\xd3\xb7\x07\x81\xe0\x1e\x30\xa3\xfc\xf6\xc0\x12\xe2\x03\x96\x7c\x7b\x00\x0f\xe4\x9b\x01\x00\x10\xe0\xce\x88\xcb\x6f\xd9\x3e\x0c\xd0\x2b\xae\x22\xc1\x1a\x38\x85\x5e\x35\xe1\xd0\x6f\xc6\xd3\xe8\x35\x1a\x0e\xbd\xf6\x86\xde\x21\xa3\x70\x06\x03\x97\x37\xa6\xb8\x0e\x9c\x74\x7e\x43\x46\x24\x38\x4c\x22\x84\x0e\x87\xe8\x60\x14\x21\xe2\x14\xfa\x4d\x7f\x01\x7d\x42\x26\x14\x46\xa3\x37\x16\x44\x8c\x45\xff\x68\x8c\x23\xe8\xa5\xf4\x9e\x12\x60\x08\x16\x91\x92\x08\x29\x17\x08\xc9\xa0\x09\x16\xa7\x08\x16\xce\x40\xf2\xb0\xe8\xed\x2a\xba\x01\x58\x02\x60\xe0\xf2\x3e\x90\x84\x01\xc8\xf7\x3a\xf9\xfc\xde\x0a\x1c\x21\x54\x56\x00\x34\x21\xdd\x37\x14\x77\x35\x14\xe0\x08\xf6\xb3\x21\xcc\x65\x08\xf5\xc9\x10\xfa\x77\xf9\x30\x2f\x34\x3e\x63\xc3\xbc\x08\xf2\x86\x0b\x0c\x89\x9b\x80\x25\xb5\x97\x48\xbe\x01\xbc\xeb\xe5\xeb\xc5\x15\x02\x2f\xfb\xff\xf7\xb8\xfa\xf6\x90\xe7\x05\x55\x2f\x07\x18\x2f\x27\x16\x0f\x9f\xa4\x4d\x75\xf2\x7f\x1b\xdb\x5d\x98\x24\x58\x64\xdf\x34\x3d\x3d\x61\x89\x16\x3a\x16\x46\xd4\x13\x4b\x33\x8d\xe4\x18\xe8\x29\x86\x3f\x3f\xdf\x8c\x21\x9f\x9e\x30\xcf\x7e\x5d\x2c\xae\xf9\xf8\xf4\x84\xfd\x8f\x24\x8a\x32\xa2\x5d\x3d\x1b\x2d\xa6\x2a\xf6\xfc\xfc\xb2\xac\xfc\x5f\xec\x98\xf8\xcd\xd4\xd0\x62\x0b\x3d\xe3\xc2\x8e\xa1\x16\x58\x68\xbd\xd1\xe0\xad\xe5\xa7\xd6\x65\xc6\xa5\x03\x36\x86\x26\xf6\x86\xfd\xd3\x13\x7e\x1d\xf9\x56\xf0\xab\x40\x6f\x5b\xdf\xcd\xff\x4a\xbe\xb7\xc3\x45\x9b\x8e\x96\xbe\x99\x7c\x0b\x7b\x2f\x47\x6f\x6f\xa0\x01\xb2\xfc\x30\x8b\x7c\x63\xf4\xf7\xfc\xdf\x74\x5f\x18\xcf\xbc\xf3\x8d\x2e\xb7\x6c\xdf\x9c\x73\xbe\x3d\x76\xba\x1c\x33\x3d\x7c\xf4\x6f\xb5\xb2\x42\xd9\x2e\x84\xdf\x6b\xfc\x5e\x86\x1b\x01\xdf\xaf\xc7\x17\x39\xde\x1f\x5c\x5d\x03\x13\xb5\xbf\x90\xcd\x92\x1b\x61\x32\xf3\x65\xf2\xf5\x1c\xf7\x2d\xac\xbe\xb7\xee\x05\x94\x3f\x6e\x0c\x2a\xb9\x32\xf3\x0d\xf1\x37\xa4\x5e\xe3\x8f\xa8\x6b\xc6\x5e\x85\xcf\xc2\x37\xc1\x06\x63\x8d\x20\x6e\x92\xf0\x1e\xbd\xef\xb7\x7c\x25\x5f\x95\x7b\xcd\x10\xd5\x4b\x33\x2f\x74\x6e\x7c\xf7\xdf\x36\xc1\xd3\x13\xec\x6e\x25\x51\xd0\x3c\x65\x55\xf4\x43\xb1\xff\x92\x31\xfe\x58\xda\x7d\x4e\xf6\x5e\x14\xbe\x8f\xff\x7b\x89\x83\x84\xf8\x90\x38\xdf\xc5\x88\x6a\xdd\x7e\xc9\xa7\xf7\x22\xdf\x90\xae\xb2\x6e\xe6\x46\x49\x76\x87\xef\xad\x3e\xf7\x93\xff\x0f\xe9\xf8\x26\x79\x3e\x8d\x82\x37\x79\x73\x93\x0a\xef\x81\xfd\x2b\x59\x6d\x9e\xbf\x92\x70\x3b\xf2\xdb\x4f\xff\x2f\x00\x00\xff\xff\x07\xae\xf6\x57\xbc\x6e\x01\x00") +var _dirIndexHtmlDirIndexHtml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\xbc\xc7\x0e\xc4\x5a\x92\xa6\xb7\xef\xa7\x28\x01\x5a\x48\x43\xcd\x90\x49\xcf\x9e\x9e\x01\xe8\xbd\xf7\xdc\x08\xf4\xde\x7b\x36\xfa\xdd\x85\xaa\xee\xe9\x2a\x40\xcb\xb9\x8b\xbb\x4a\x9e\x4c\xe4\x2e\xe2\x8b\xff\x8f\x08\x9e\x7f\xf9\x3f\x38\x93\xf5\x62\x8b\xff\x4b\x73\x8c\xc3\xff\xfc\xa7\x7f\xfd\xd7\xbf\xfc\x9f\xdb\x3c\x1f\x7f\xf9\xe7\xff\xf1\x97\xff\xf6\x97\x7f\xfb\xb7\x7f\xfa\x97\x7f\xff\xfe\x5f\x9a\x32\x2d\xfe\xe7\x3f\xfd\xcb\x7e\xbc\x43\xf9\x3f\xff\x09\xfc\x2f\x7f\x71\xe7\x73\xcb\xcb\xbf\xfc\xd7\xbf\x54\xed\x50\xb6\xf9\x3c\xed\xff\x6d\xde\xea\xbf\xfc\x17\xf0\xbf\xb5\x4b\xb5\xff\xd7\xff\x37\x1b\xd2\xa9\xff\xcb\xbf\x66\x69\xde\xd7\xdb\x7c\x4e\xc5\x7f\x6d\xc7\xb4\x2e\xff\xf9\xdc\x86\xff\xab\x48\x8f\xf4\x9f\xff\x76\x04\x97\xa9\xfe\xef\x59\xba\x97\x38\xfa\xff\xb4\x01\x63\x3a\x37\xa4\x8a\xf5\x4c\xd3\x34\x6d\xb8\x7e\xc3\xfb\x35\x4d\xd3\xcc\x5f\x8f\xb4\xcd\xd2\xf1\x5f\x3f\x2b\x12\xa4\x9a\xbf\x3e\x88\x91\x23\x84\x92\xe3\x65\x70\x02\x15\xb0\xf0\x26\x36\xc3\x24\x22\xd5\x26\x2e\xa3\x64\xa1\x30\x25\x81\x32\xc4\xa1\x83\xe5\xf9\x30\x58\x7f\xfd\x43\xc8\x28\x0e\x2f\xf8\xa5\xb1\xf2\x7e\xf7\xd3\x1e\x9e\xb6\xa7\xe2\xa7\x07\x34\x3a\xbc\x32\x1f\x3e\xb8\x2f\xab\xbc\xe8\xf3\x8f\xb8\x67\x2c\x72\x68\xd5\xad\x80\x8d\x07\xd6\x44\x30\xb0\xd3\x99\xad\x4f\xc4\xdc\x35\x68\xa3\x8d\x6d\x81\x5a\xa3\x6a\xd8\x94\x9c\xcc\x7e\x9d\x62\x15\x62\xba\xf8\x9e\x9f\x4e\x74\x5f\x71\x05\xa7\x83\x71\x75\x3c\x25\x40\x45\x51\x69\x4b\x04\x07\x76\x50\x2a\x75\x4e\x27\x2a\x69\x77\x29\x23\x6b\x18\x3f\x32\x6e\x71\xf3\x5e\xbc\x50\xd5\xe4\xd3\xf1\x98\x28\xca\xe6\x26\xf3\x59\x34\x31\x56\xfc\x7b\x4a\x77\x45\x4c\x87\xdd\xa3\x5d\x3e\xbd\xb7\xf9\xc8\x43\xf5\x98\xac\x11\xa7\x5a\x50\x67\x78\x1e\x65\xbd\x57\x34\x4a\xb4\xc2\xae\x3c\x18\x3a\x0b\x3d\xf2\xda\x48\xf9\xc7\x65\x2d\x69\x06\xdf\xa2\xb9\x7e\x0a\x85\x65\xe6\x54\x63\x5b\x6b\xd2\xda\xfd\xf8\xdc\x4a\xa6\xbb\x22\xea\x8c\x93\xb7\x38\x70\x5e\xbe\x9d\xce\xad\xc3\x3b\x8f\x91\x5e\x99\x58\xd6\x60\x13\xec\x95\xcf\x0e\xdc\xe3\xc7\x84\xba\x7e\x86\x43\x2b\x06\xfb\x7b\xbc\xf8\x91\xed\x06\xd4\x47\xc7\x1f\x46\xc1\xe6\x91\x35\x34\xc3\xdf\xb4\x32\xb0\x17\xf6\x3f\x10\x39\x6a\x25\x80\xee\x34\xb8\x7a\x41\xe6\xcb\x24\x93\x56\x94\x1f\x5e\xf5\xa3\x47\x3e\x32\x1f\xbc\x9e\xf8\x40\x39\x43\xe6\x1b\x7b\x47\x61\x1c\x2b\x16\x13\x86\xdb\x83\xd4\x1c\x16\xb7\x0e\x14\x1e\x7e\x83\x94\x2e\x41\xa8\x7f\x40\x24\xfd\x18\xc7\x84\x82\x3d\xd3\x85\x84\x47\x58\xce\x4d\xd4\xbb\x4c\xaa\x58\x0e\x6a\x80\x4b\xf0\x8b\x68\x28\x91\x0b\xcc\x3b\xb1\x6e\xd0\x9a\x1f\xf5\x04\x2b\xba\xbe\x69\x2d\xe3\xe8\xa8\x22\xb8\xc2\xee\xff\x16\x28\xae\x1f\x98\x8e\x8a\xb1\xb1\x2c\xff\x8f\xff\xfb\xbf\xff\x43\x00\x6e\xe5\x52\xa6\xc7\x3f\x4f\xf3\x7f\x3c\xfd\xe3\x6f\x7b\xfb\x95\xff\x9c\xcf\xd3\x91\xb6\xd3\xbf\xfd\x47\x08\x2f\x69\x5d\xfe\xb9\x22\x78\x6c\xfe\x23\x82\x97\xdd\xff\x8e\x0b\xfa\xd1\xb1\x55\x15\x8d\xf9\x82\x91\x97\x90\x50\x10\xfc\x82\x99\x5d\x07\x1a\xfe\xec\xd5\xaf\x6f\x9d\xe7\xb7\x90\xa1\xb5\x0b\x15\x15\xae\xe2\xb9\xd1\xe4\xa5\x5d\xf0\xd6\x80\xf5\xf8\x87\x6e\x5b\x57\x86\x6d\x5e\x55\x54\xde\x0d\x04\x81\x09\x67\x08\xf5\x78\xd7\xf9\xaa\x17\xce\x09\x2d\x06\x7b\xed\xa8\xe0\x82\x04\x30\x0c\xfb\x2e\x9d\x32\x52\xf9\x37\x6f\x29\xb6\x5f\xd9\x4b\x99\x53\xe6\xf3\xcc\x53\x73\x83\xac\xb6\x61\x17\xd9\xa5\xf6\xfe\x28\x30\xfa\x11\x3b\x7f\xe4\x56\x0c\x6f\x87\xe4\x52\x38\x28\x9d\x90\x73\x45\x91\xf6\x01\xb9\xff\xe9\x24\xf1\xb9\xcd\x2e\xc3\x14\xb7\x48\x6c\x7c\xa0\x3c\xce\xcc\x0f\x2a\x27\x9f\x37\x65\xdc\x43\x04\x04\x2a\x76\x8d\xe9\x56\x77\xcd\x43\x12\x8c\x23\xa4\x4a\x35\x10\x49\x23\xad\x24\x06\x59\xe7\xdd\x44\x8d\xc7\x23\xfd\xde\x20\x53\x97\xb9\x64\x88\xa2\xd2\x5d\x95\xdd\xc8\xd5\x58\xc9\x02\x47\x47\xca\xd2\x9d\x67\xdd\x12\x45\x27\x0b\x81\x8c\x5a\xd0\x32\xe4\x47\xad\xd8\xd0\x33\x09\x25\x56\x9a\x26\x04\x9b\x37\xbf\xc0\x41\xdf\xb8\xec\xc4\x92\xa1\xc9\x16\x6b\x7d\x4f\x9f\xf0\xa0\xa0\xfc\x2e\xcb\xed\x04\x06\x10\xc5\xd1\x5e\xe6\x6b\x42\xff\x16\x06\x25\xcb\x9e\x9e\x6e\x0a\x44\xc5\xe4\x41\x34\x08\x35\x40\x71\xf6\x6e\xbe\x8b\xd0\xdc\x90\xb0\x6b\xb0\xaa\xee\xa0\xe5\x78\x21\xf3\x70\xb3\xcf\xe3\xd9\x58\x4c\x9f\x0b\x24\xd8\xa3\xc0\xd3\x05\x77\x3d\x52\x1e\xa8\x07\xaa\x68\x52\xff\xe1\xe1\x23\x4a\x5a\x81\x98\xe2\xb6\x4d\x0f\x05\xb9\xb0\x9d\x74\xc0\xdf\x6b\xb2\x86\x66\x9e\x77\xd7\xf3\x5a\xeb\x65\x23\x4b\x15\x8a\xb4\xc8\xa9\x48\xbb\x3b\xd7\xcf\x82\x2d\x2a\xf6\x2d\x85\x7a\x2e\x85\x4a\x6c\x8e\x7e\xf7\x33\xbb\xcb\x9e\x8f\xf3\x3d\x0e\x6c\x92\x74\x8d\x17\x7b\xf6\x7d\x70\xdb\x47\x48\xb4\xbb\x7b\x9f\x2e\xe0\xfd\x51\x32\x17\xb4\xdd\x26\x39\x6a\x90\xdc\xa4\xef\xb3\xcd\xcf\x4d\x85\xe6\xb1\x37\x1a\x8f\x6b\x5b\xb7\xa5\xb9\x63\xfd\xa1\x9e\x58\x9a\xbe\x54\x81\x99\xa3\x28\x95\x2a\x7a\x73\xd9\x84\xe3\xa1\xfa\x0d\x95\x5a\x90\xd5\xf1\xf2\x05\xd5\x44\x75\xdf\x90\x7b\x38\x45\x81\xc6\xe4\x0e\xce\x0f\x4e\x05\x54\x08\x04\xa6\x55\x17\x4f\x0e\x79\x2c\xbc\x97\xb6\x6d\x06\xc9\x12\x83\x1c\xa8\x83\xc0\x64\xa1\x81\x14\xdd\x2f\x02\x75\x9f\x9b\xdd\xb7\x56\xa7\x9e\xfa\x14\x3a\xe2\xba\xae\xe3\x85\x95\x7a\x55\xf4\x76\x49\xc6\x0c\x53\x9f\x3b\x06\x6d\x3d\x99\x65\xcb\xe5\x8a\x30\x84\x96\xf9\xca\x3e\xd2\x5f\xeb\xb3\xe3\xec\xb5\xcc\x58\xf0\x5b\x0b\x3b\x75\x51\xa8\x42\x73\x2a\xf3\x9a\x81\x69\x05\xbe\x37\x58\x20\x9f\x67\xe8\xb8\xdf\xa7\x66\xd5\xee\x38\x9c\xfa\x75\x51\xd0\xd9\xf4\x01\x5b\x74\x5a\x31\x10\x4c\x5f\x77\x50\x20\xfb\xd1\x74\x36\x6a\x1d\xbb\x55\x4c\xeb\xd4\x7f\x28\x21\xd2\x34\xff\x73\xf1\x61\xfa\x4f\x3e\x40\x7e\xff\xb3\x78\x88\x8f\xab\x63\x3b\x83\xe1\xa2\xfd\xbe\x09\x78\x6b\x66\xf2\x9d\x9f\x35\x47\x61\x62\xe8\xa7\x5b\x52\xc7\xee\x48\x7e\xcd\x75\xee\x81\xe8\xaa\x28\x06\x66\x5c\x52\x33\xcf\x4d\x6e\x4e\xd6\x8d\xc6\xbc\x28\xf7\x6c\x03\xcc\x9a\xc8\xa8\x23\x92\x10\x53\x82\x14\x63\x09\x5f\x9d\xd9\x78\x79\xd7\x2a\xca\x95\x7c\xd6\x65\xea\x24\x28\x89\xf0\x8a\xc0\x18\xb7\x21\xbd\xb6\x10\xf1\xaf\xcd\x16\xf9\xe9\x76\x54\x6d\x6c\x26\xa9\xae\x00\xdf\x09\x15\x0b\x32\x28\xeb\xca\xb9\xc2\x92\x21\x17\xdf\xdd\xfa\xa5\xd8\x6f\x6c\x2b\x93\x7b\xb3\xeb\xe3\xc9\xf1\x63\xb3\x8d\x9e\x3d\x4e\xf6\x1a\x7d\x16\xa3\xa4\x4d\xd0\xd8\x6d\xcf\xad\x02\x92\x5f\x54\x9e\xec\xaa\x10\x66\x07\xec\x2a\xd2\xd9\xb9\x41\x8f\x35\xf9\xf4\xa2\x4d\xfc\xc6\xb8\xec\x72\x9a\x41\xa9\x6b\x19\xcb\xf3\x53\xf2\x7c\x80\x80\xc2\xef\x70\x55\xa6\xaf\x4a\x62\xad\x1a\x31\x80\x93\xbe\xd0\xab\xa6\x18\xf3\xc9\xd9\xb1\xe2\xbf\xd3\x02\xeb\x72\x5a\xc6\x72\x6d\x78\xbd\x3e\x8b\xf2\x07\x29\xf7\x08\x70\xa7\x2f\xbf\x7e\xe1\x0d\xeb\x09\x67\xef\xac\x57\x11\x58\x38\xe5\x36\x32\x25\xff\x48\xbb\xd7\x86\x46\x8b\x00\x83\xbe\x7c\xce\xcd\xf5\x2d\xf9\x3d\xac\x4c\x7b\xe3\x97\x95\x57\x35\xb2\xc3\xd9\xb7\x16\x66\x08\x8d\x52\xdf\x7d\x57\x3a\x5e\xa9\xb9\x4d\x61\xce\x81\xb2\x4e\x74\x7d\xf7\x35\x4b\x27\x38\xe0\x17\x1a\x4b\x1d\x77\x67\x27\xe4\x52\x7c\xed\x2c\xf4\x09\x23\xc5\xc8\x8a\x33\xc8\x80\x16\x0a\xcf\xf3\x96\xc9\x96\x1c\x9a\xc7\x81\x44\x44\x7b\xf5\xc3\x04\x40\x90\x47\x96\x20\x30\xd9\xa0\x15\x46\x71\xfb\x60\x0e\x67\xc8\x8e\xa9\x78\xad\x5b\x07\x4d\x92\xcf\x49\x45\xa6\x2f\x6e\x15\xc9\x84\x47\xd4\x9c\xc4\xaf\x18\xc4\x19\xe1\x07\x7d\x28\x56\x3c\x76\xff\x91\x28\x3b\xee\x55\x99\xe5\x84\x53\x7b\x54\x7a\xfe\xc4\xe4\x2e\xbc\x95\x71\x76\x58\xc8\xb4\x21\xca\x5a\xab\xe0\x59\x9d\x95\xd2\xa2\x03\xe9\x94\x8b\x12\x43\x58\xcb\x82\x95\xaf\xc9\xc9\x5d\xd4\x5f\x9c\x99\x00\x1a\x16\xfb\xfc\xf1\x26\xcd\xa5\xa4\x6e\x5f\x68\xa7\x6b\x19\x13\xc2\x50\x0f\xd8\xf1\x46\x06\x6d\xd4\x64\xc6\x27\x72\xb5\x50\x73\xfd\x49\x4c\xaf\x0e\x41\x4c\xdb\xcc\xe6\x0f\x5f\xcb\x40\x91\xed\xb6\x15\x1a\x8f\x76\xd3\xef\xb5\x21\x2b\x3d\xd5\xa6\x5a\x63\xa5\x01\x95\x81\xfe\x08\x9c\x8a\xcb\x16\xdf\xcb\x65\x62\x62\x3b\x6e\x7f\x75\x33\x30\xa1\x8a\xf1\x9c\x99\xe8\xbb\x3b\xdb\x01\x09\xbb\x98\x5c\xdc\xf5\xa2\x4e\x1b\x1c\xdc\x13\xe5\xe3\xef\x55\xd3\xb3\x05\x00\x53\x6f\x7d\x32\x24\x19\x0e\x84\x10\x82\x33\x7e\x78\x04\x58\xe7\xd1\x4a\xd7\xe2\x45\x34\xcd\xf3\xd3\x42\xa6\xdd\x4a\x29\x98\x08\x2a\xb6\x70\xb6\xb1\x91\xa9\xcb\xc0\x52\x18\xaa\x70\x15\x57\x0f\x91\x90\x64\x10\xe5\x46\x94\xe1\x16\xf6\x4d\xd0\x07\xef\xfe\xa6\xe9\x71\x4e\x87\xfc\x19\x0c\xfa\xf7\xb7\xec\xe4\x07\xc1\xeb\xdd\xd3\x1e\x59\xf6\x7f\x8b\x19\xed\x9f\x0b\x19\x3d\xf6\x77\x49\x01\xfd\x2e\x7e\xe0\x7d\xcb\xb3\xbe\x64\x65\x68\x3b\x75\x05\xbb\x55\x62\x7f\x1c\xd4\xb8\x99\x3d\x01\xfd\x69\x88\x97\x9d\xa0\x0d\x02\xf4\xb5\x47\x08\xb3\x80\xb5\xb5\x9f\xa1\xb6\xad\xef\x6a\x13\x9e\xff\xe8\x07\x7d\x09\xbf\x23\x16\xe7\xe8\x36\x6e\xe2\xbe\x88\xef\x8e\xeb\x43\x8d\x10\xed\x46\x08\x0a\x23\xb0\x05\xfb\x08\xc2\x84\x7e\x73\x13\x02\x20\x17\x34\xe4\xd7\x11\x69\xac\x36\xd5\x20\x16\x22\x95\xec\xe2\xad\x19\x6f\x51\x55\x75\x50\x6d\x3f\x2a\x96\xae\x9d\x4f\x81\xe4\x04\xa7\x67\x2a\xe6\x0c\x73\x0f\x5b\x05\x8a\xf7\xbb\x92\xef\xbd\xc1\x5a\x1d\x46\xbd\x23\xe4\xb7\x16\x74\xe0\xb9\x8c\x3c\x9d\x16\x14\x3c\xb0\x82\x9e\xc7\x48\x62\x5e\xd8\xf7\x19\xd3\x84\x75\x7a\x00\x19\x0a\xcc\xad\x0c\xb7\x7c\xed\x9c\xa5\x07\x0a\x75\xa8\x44\xc4\x6b\xf1\xcd\x87\x43\xee\x84\x56\xc2\xf3\x48\xd6\xd8\x8f\xc7\x75\x71\x6b\xcc\xd4\x6b\x09\x89\x6d\x33\xd3\x30\x2a\x84\xc0\x73\x18\x96\xed\x75\x10\xa9\xac\x7b\x95\x5f\xdb\x90\x71\xc5\x00\x75\x90\xcb\x26\x76\xb9\x71\x73\x2f\x11\xbc\x45\x7a\x10\x1a\xfe\x61\x0c\xb6\x0f\x67\x10\x83\x61\xa8\xd7\x04\x40\x7b\x0c\x38\xe4\xda\xae\x2e\xde\x3c\x49\x1f\x07\x98\xba\xc0\x9f\xde\x47\xb6\x7d\x7f\x50\xea\x7d\x50\xb1\x92\x30\x08\x99\x2f\x4c\x31\xdb\x74\xa2\x14\xda\xc5\x8a\xcc\x5b\xcd\x16\x83\x47\x45\x4f\x41\x4b\xfc\xe2\x51\x8d\xe4\x20\x97\x86\x37\xbd\xd5\x10\xc5\xa5\x22\x36\xb0\xbb\x2f\x18\xd0\x92\xf7\x09\x3d\x77\x05\x4b\x8e\x68\x7a\x32\x6b\x4a\x6b\xa7\x5b\x97\x1f\x11\x30\x3f\xe7\xe0\x5c\x3f\x34\xed\xcb\x4f\x19\x4d\xf0\x3f\x85\xd1\x15\x98\xbb\x47\xab\x2e\x7e\xca\x3d\x42\xe1\xec\xd6\x4a\xd5\x71\xd7\xe6\xa9\xcf\x71\xd3\xf2\xcb\xf7\xb4\x69\x63\x8d\x0f\x82\x49\x51\x63\xe7\x7c\x73\x83\x6f\xe8\xd3\x9d\x68\x21\xb4\xbb\xa7\x7f\xd2\x6c\xdc\xdc\xb6\x73\x0b\x97\xf2\x9c\x0b\xdb\xf1\xb1\xef\xe7\xb9\xd9\xcf\xa9\x3a\x16\xe6\x90\x4c\xf1\xcf\xeb\x6b\x3a\x8f\xe8\xe6\x69\xcc\x5b\xdb\xb9\x5d\x9a\x0d\xe4\x44\x4d\x4c\xf1\xb8\x2a\x60\x25\x5c\xa6\xa6\xaa\x93\x0b\xa4\x96\x6b\xd7\xa7\x3d\x41\xe9\xc1\x26\x28\x2f\xf1\x30\xf5\xdb\x85\xa2\xdb\x46\xe8\x8f\x01\x85\x6d\x50\x6b\xd2\x86\x09\x19\xee\xd2\x2b\x98\x93\x4d\xa8\x6f\x0e\x5d\x83\x76\xa1\xf9\x57\x1f\xa6\x54\xa0\xb7\x2f\xed\x40\x0e\xe2\x5a\x3d\x1a\x14\x5a\xb0\x5f\x15\xde\xc8\x6a\xd2\x75\x27\x59\xd0\xc1\xfe\xe9\xa9\xab\x61\x87\x0f\xfe\xfa\x95\xee\x75\xb6\x81\x8f\x58\x06\x08\xa0\x6f\x08\x28\xef\xac\x6c\x43\x33\x3e\xc1\x7e\x5d\xb2\x91\x9e\x32\x31\x94\xa5\x44\xcb\x87\x04\x28\xcd\xd0\x96\x69\x07\xca\x04\xdb\x38\x24\xfe\xb1\xa9\x5f\x55\x7f\xae\xe4\x9f\xff\x53\x2f\xf4\x3e\x75\xac\xfc\x8f\xf7\xa3\x64\x4c\x16\x1e\x49\x3d\x46\xcb\x14\xc1\xf2\x0e\xc1\x77\x0e\x97\x3d\x9a\x8d\xf0\xd9\x57\x55\x05\x05\xa4\xe8\x09\x99\x6b\x9c\xae\xc1\x39\xaa\x66\xbf\x23\xe6\x9a\x4a\x77\x96\x89\x55\x0f\xf7\x65\x4b\x4a\xc3\x63\x59\x09\xc3\x87\xd3\x44\xc5\x3e\xec\x4e\xa8\xe7\xd1\x17\xfd\x4e\xb8\xb3\xbc\x3f\x6a\xd9\x36\x04\x4e\x5a\x13\x24\x58\x23\xe5\x1e\xc4\xd4\x0e\xbc\x32\x3b\x66\x15\x6b\x30\x55\x1d\x56\x96\xa7\x85\x04\xd4\xaf\x52\x25\xa2\x3a\x8b\x29\x10\x30\x72\xe2\x7f\x78\x39\x00\xe0\xeb\xc3\x23\x23\xb8\x61\xa2\x2e\xa1\xa2\x06\x39\x64\xd6\x3e\x33\x43\xb0\x8a\x1a\xdc\xe8\xe3\x33\x81\xe9\x0f\x10\x16\x27\x25\xfb\x91\x50\xb6\x26\x0d\x2e\xd3\xef\x91\xca\x38\x3d\xeb\x80\x2b\xbe\x25\x5b\xa8\xdf\x2a\x0e\xb4\x2a\x7a\x0f\x59\xb0\x3f\x0a\x0c\x97\xa7\xe9\xa6\xfd\xe9\x40\xc7\xb9\x7b\x12\x6b\x44\x85\xa5\x8a\x9f\x89\x57\x53\x19\xd2\xe7\xfc\x1d\x5c\xec\xba\x5a\x49\x99\x1e\xee\x9e\x11\x03\xe7\xf9\x43\x20\x09\x75\x9e\xfd\xcd\xdd\xd5\xb0\xff\x6a\xe8\x49\xe4\x18\xa4\x0b\x50\x9c\xde\x03\x8c\x82\x2a\x7b\xe3\xcd\xe5\x1c\x9e\xb4\xf8\x47\x62\x70\x90\x64\x70\xfb\x4c\x1f\xf9\x76\x18\x41\x3f\xa0\x56\xa6\x5b\xfd\x01\x34\xf6\xdd\xc9\xae\x12\x15\xde\x6f\x7b\x38\x5c\x12\x93\x83\x5d\xbb\xa2\x66\xee\x08\x56\xfb\x9e\x17\x96\x6e\x63\x1c\x17\x5c\x70\x1e\x91\x8c\xc0\xd8\xc0\x85\xf5\xc1\x27\x68\x05\x0e\x5b\x85\x61\x93\x2e\x81\x0b\xe5\x74\x7a\x4e\x49\x84\x5b\xa0\x1d\xc2\x67\x99\x2e\x45\x2a\xa3\x7a\x62\x38\xe6\x67\xf6\x70\xd8\x8e\x2a\x47\xc4\x5b\x8a\x1d\x17\x16\x65\x2f\x45\x96\x79\x5c\x48\xac\x63\x91\xf9\xd6\x1b\x87\x17\x12\xad\xa7\x78\xa2\x65\x98\x75\x33\x37\xb3\x1a\x7e\x11\xe8\x94\x87\x3f\x93\x4b\x7d\x7a\x08\xc3\x9b\x9b\x5d\x8c\x6b\x4a\x71\xcd\xc2\x25\xe0\x41\x88\x1d\x57\x36\xa6\xd6\x9e\x7f\x65\x83\xc9\xcb\x0c\x3e\x69\xce\x31\x6c\x32\x73\x43\x3a\x08\x3e\x59\x50\xe7\x91\xb5\xdb\x11\x80\x86\xd3\x45\x5f\x35\x1e\x76\x69\x70\xde\x64\x26\xf8\xdd\xe5\x59\x18\x51\xb1\x8b\xde\xa3\x06\x94\x28\xf8\x4b\xfa\xd3\xb9\x9e\x92\x71\xb1\x89\x7f\xe0\x77\x81\xd5\xb5\x79\xac\x39\xc0\xbc\xd8\x05\x49\xf6\x28\xe8\xe5\x1d\x74\x6a\x4f\x6c\x55\x75\xed\xef\x2d\x1d\x6f\x2f\x9d\x00\xb6\x67\xfa\x93\xe3\x98\xec\xc6\x12\xe3\x0c\xaa\x92\xa1\xc2\x9e\x7d\xb9\xa3\x0d\xf1\x2d\x2c\x2a\xd0\x09\x2b\xb9\xa9\x05\xa4\x5b\x66\x31\xe2\xad\xc8\x6e\xf0\x80\x5e\x4f\x59\x9d\xa3\xf0\x29\x7f\xab\x14\xd6\xd7\x17\x57\x91\xeb\x2c\xfc\xf6\xb8\xc4\x7e\x4c\x1e\xb4\xd2\xa7\x49\xe5\xca\x3a\x6b\x93\xfc\xe2\xe8\x77\x08\xb7\x51\x25\xcc\xe3\x52\x26\x62\x84\x3d\x9d\x4b\xab\x83\x43\x78\x0f\x4e\x20\x92\xcf\x2a\x3d\x07\x60\x4c\x5c\x36\x68\xc6\x6c\x52\x5e\xc3\x36\x5e\x48\x0e\x89\xbb\xd0\x40\xf8\x89\x80\x15\xaa\xea\x34\x73\xb9\x61\xc5\x49\x63\xa6\xc2\x7f\xb3\x1e\x8c\xe2\xf8\x18\xbf\xf5\x4a\x5d\xd7\xff\xe3\x7f\xcf\x7b\x5c\x7f\x32\x21\x31\xfe\xfe\x2e\x24\xc8\xe3\x84\x20\xda\xb7\xa2\x24\x37\xa0\xe9\xf3\x96\x15\x56\x6d\x64\xa1\xef\x5e\xa6\xa7\x50\x5a\xd9\xb9\x2c\x1f\x26\x03\x68\x1b\xa0\x99\x84\xa4\xe1\x1d\xa0\xe5\xbe\x18\x61\x1c\xb7\x7d\x45\x16\x42\x95\xe9\xa5\xfa\xa7\x2e\x8e\xd4\x62\xf3\xa8\x88\x7d\xa6\x20\x99\x28\x75\x00\xaa\xff\x78\x7b\xf3\x2e\xf7\x15\x2d\xeb\x2c\xcb\x32\x07\x80\x1f\x5f\xdb\xcc\x23\x2d\x00\x48\x8d\xd9\x7b\x6e\xad\x93\x14\x4f\xa7\xa4\xad\xca\x70\x48\x08\x9c\x3f\x60\xa1\x52\x12\xc3\xc7\xf4\x01\x6a\xce\x24\xcb\xcc\x03\x42\x0f\x86\xf8\xaf\xa5\x8c\xa4\x05\xf3\x6d\x4d\x8b\x6b\x82\x75\x9b\xa1\xc5\x6a\x61\xcd\x65\x35\xb6\x13\xa6\x10\xe2\x7a\x2c\x79\x89\x71\x73\xea\xf2\xfc\x41\xbc\x3b\xef\x29\x9d\x69\x5d\x1f\x9a\xf2\x4a\x6a\xb7\x48\x18\x93\x08\xd1\x0b\xea\x5e\x59\xff\x6e\xf9\xc0\x00\xbf\xd4\xae\xa4\x03\xba\xaa\x8c\x29\xb1\xd3\x7e\x4f\x2b\xa8\x97\x01\x4b\xa6\xdf\xef\xcd\x34\x14\x6c\xc1\xa1\x97\x59\xf3\xc6\xa6\xd6\x76\x44\xdb\x6d\xe6\x76\x95\x71\x66\x46\x91\x10\x3e\x33\x72\x42\x1a\xe7\xd0\x12\x8f\xa8\xbd\x77\xea\xf1\xba\x67\x23\xaa\xa6\xcd\x67\xa1\xa7\xa7\x91\x12\xee\x66\x7f\x60\x2a\xff\xf8\xa0\x55\xe6\xe1\x04\xed\x46\x75\x74\x29\xf9\xf9\x11\x24\x6e\x3f\xdf\x95\xf9\x09\x13\xac\x50\x7a\x01\xf0\xf6\xe6\xbe\xdf\x6c\x73\x85\x2f\x26\x95\x12\xc6\x40\x9b\x31\xa6\x94\xbb\xda\x50\x7a\x02\x8f\xb2\xe5\x19\x14\x4b\x12\xee\xe6\x5a\xbd\x99\xf9\xc7\x83\x0c\x60\x8f\x39\xf6\xf4\xfb\x7e\x19\x34\x79\x88\x2c\x14\x8c\xf8\xa8\x98\x01\xc7\x6f\x8a\x86\x71\xdd\xca\xbf\x8f\xc0\xf3\x45\x52\x97\x25\x95\xb2\x83\x55\x26\x38\xf0\x8c\xf1\x6b\x83\x97\x7b\x64\xad\xad\xff\x00\xaf\xa7\xea\x9b\x76\x42\x9b\x0a\x9f\x65\xc9\xa2\xa4\x31\xa6\xe5\x06\xde\x14\xa5\x31\x29\x69\x71\x0d\x1d\x64\x87\x0c\x5f\x36\xd7\xf0\xdd\x4b\x5a\x3a\xec\xc2\x9a\x1e\x97\xa7\x9f\x30\xa0\x5f\xbd\x74\x54\xf1\xb0\x67\xef\x91\x77\x46\x8d\xd3\xae\x8e\x81\x74\x8d\x6a\xfb\x30\xb2\x34\xe1\x9c\xbf\xd8\x4c\x17\x44\x23\xa5\xd8\xc0\x39\xa9\xc8\x5c\xb0\xc0\xd8\xd2\x0b\x98\xa9\x60\x3e\x92\x10\x58\x46\x8b\x7b\xc3\x7b\xe5\x8e\xb1\xcb\x71\x92\xf9\xdd\x8d\xb1\x21\xde\xd4\x1f\xe0\xcf\x61\xee\xcd\x9a\xde\xf1\x12\xfd\xca\x36\xcc\xb0\x8c\xfb\x80\x46\xd0\x00\x89\xdf\x6c\xeb\xc8\xaf\x4c\x99\xb9\x48\xf8\x36\x85\x56\x43\xdf\x01\x9e\x35\x9d\xca\xfd\xb0\xbb\xa2\x26\xb1\x5a\x8a\x7f\x9c\x2e\x36\x09\x2c\x75\xaf\xb8\x4f\x8b\x60\xad\x86\x34\xc5\x70\x35\x4a\x17\xe2\x60\xae\xfe\x8e\x71\xe6\x98\xfb\xe7\xda\xb0\x63\xd2\x31\xb5\x4a\xed\x5c\x5d\xc3\xe3\xe6\xd8\xb3\xab\xea\xba\x4e\x31\x52\xb4\x0e\x4f\x35\x68\x84\x15\xe0\xf2\xd5\xc4\x30\xe9\x68\x7b\xed\xdb\x4d\x73\x25\x15\xd6\x20\x6b\x2b\xb5\x40\xff\xb1\x9c\xc8\xc6\xe5\x4f\xc6\x89\xe4\xef\x3d\x0a\xe0\xb7\xf9\x03\x1f\x83\x3f\xe4\xa2\xe2\x00\xba\x56\xf8\x3e\x0e\x19\x63\x8b\x45\xa3\x52\x5e\x64\x12\x9f\xbb\xa0\xa2\xc2\x71\x52\xc6\x27\x60\xde\x20\xdf\x06\x9d\xf3\xe4\x20\xbe\x0e\x38\x3a\xd9\x76\x55\x40\x69\xe7\x97\xe2\xac\xa9\x86\xd8\x1a\x5d\x51\x99\xc3\x84\x75\x06\x65\x91\x22\x59\x9d\x0b\x78\x49\x82\x6f\x89\x81\x05\x31\xb5\x7a\xd2\xd4\xfc\x33\xa9\x54\x95\x79\xdb\x88\x2d\x19\x23\xea\x09\xd7\xd7\xec\xbb\x02\xc1\xdb\x78\x7e\xea\xe1\xfc\x0c\x27\x92\x52\x5a\x56\x18\x29\x91\xd3\x94\x1f\xc2\xfc\xde\x67\xd4\x41\xbb\xc8\x8f\xc8\x77\xd9\xfa\x08\x50\xeb\x45\xd9\x2b\x46\xf2\xfe\x45\xcb\xdf\x83\x71\x83\xc6\xa6\x62\x96\x7d\x5d\xc4\xe5\xf3\xb9\x8b\x98\x69\x97\x98\x64\x39\x2e\x6b\x5b\x2a\x6a\x2d\x3b\xaf\x83\x91\x84\x86\x57\xe3\xa2\xd3\x5c\x9e\x88\x72\x4b\xa2\xe8\xb4\xbe\xd6\xec\xfa\xac\x26\x2e\x2a\x43\xe2\xc1\xcb\x0c\x35\xd6\xbe\xa6\x88\x34\x04\x50\x9c\xc5\x2c\x8c\x47\xec\x55\x75\x55\xbf\x10\xd4\x6a\xdc\xac\x95\xb3\xba\x49\x16\x62\x1d\x91\x8f\xc2\xf4\xf3\xef\xb6\x7d\x05\xbb\xa3\xc9\x6c\xef\x02\xb5\x4b\x95\x6f\xbe\x74\x0e\xb4\xb1\xfa\x79\x95\x46\x84\xf3\xeb\x2d\xa3\x12\xce\xe9\x93\xe6\x6c\x43\x64\x46\xe6\xd2\x52\xf1\xf4\x04\x27\xe5\xaa\x06\xf9\x0d\x8c\x17\xb6\xd4\x72\x8e\x5d\xa6\x42\x0c\xaa\xd8\xe7\x80\x5c\xa6\xbd\xe8\xa4\x52\xec\xbd\xa9\x6d\x05\x7b\x71\x39\xd7\xd1\x7b\x77\xd4\x98\x27\xf7\x73\xab\x6a\xe9\xdc\xeb\x86\x03\xe7\x53\x92\xad\x06\xad\xbf\xf9\x2a\x12\x51\x26\xa9\x0e\x5c\xe9\xdf\x6d\x82\xc5\xfe\xb8\xf7\x09\x31\x2d\xa3\xec\xc6\x7e\xc1\xda\x4d\x2b\xb4\xc2\xca\xd8\xf9\xc0\x75\x14\x67\xab\x51\x1e\xf9\x87\x59\xb3\xe9\xc8\xbf\x9c\x73\xa1\x89\xa4\x1f\x31\x24\x68\xe0\xbb\xf8\x98\x51\x13\x38\x19\xf2\x9d\x3f\x14\x2d\x2b\x0b\xbd\x2b\x2d\x26\x65\x3d\x5b\xaf\x9b\x07\xc5\xce\xe1\x0d\xfb\xef\xd1\x03\xdf\x86\x1d\xdd\x6e\xb4\x4a\x30\x7f\x78\x4c\xaf\xec\xd6\x3e\xd6\x34\xe2\xed\xaa\x6e\x4e\x06\x87\x30\xc2\x57\x02\x9a\xfb\x86\xbb\x49\x35\x05\xe5\x1b\xd1\x70\x2f\x83\x20\xba\x37\xb9\xa3\xaf\xd2\x5a\xb0\xa3\xa7\x3c\x38\x66\xf7\xd4\x00\xbd\x5b\x8d\x18\x0c\x48\x75\xca\x03\x7c\xc8\x26\x03\xc5\x29\xf5\xab\x7b\xb3\xa5\xc6\xa7\xa1\xd3\x01\x2a\xfb\x79\xeb\x7f\x6d\x0e\xf6\xa2\xc6\x98\x8e\xfe\xbc\xb0\xfa\x5b\x5d\x2a\xf8\x25\x76\x66\x78\x8d\xdc\xc1\xbc\xd8\x00\xf0\xb1\xbf\xe6\xe4\xa6\x2d\xb9\xfd\xfc\x47\x37\x64\x86\x01\x34\xc7\xf3\x7c\x6d\x43\xfd\x62\x87\xd4\xdf\xe1\x83\xa7\xa9\x3d\xf2\x36\x66\xc6\x47\x46\x91\xbb\x4d\xb4\xeb\x2e\x67\x26\x52\x55\xa6\x3a\x6f\xd0\xfc\x26\xf0\x73\x6f\x98\x3a\xa8\x99\xfd\x65\x28\xa1\x57\xb7\x1f\xd3\xb4\xbf\x6b\x6d\xb8\xa1\xb6\xaf\xfc\x91\x86\xe4\x4f\xd6\xbd\xcc\x9f\xbf\xcf\xe7\xfa\xdf\xf6\xb7\xee\xe5\x98\x4c\x7d\x3d\x2b\x6c\x2a\x1a\x6c\xd9\x9c\x8a\x97\x0e\x8d\x92\xb8\x7e\xc2\xe0\x78\x0a\x49\x77\xb4\x5b\xa0\x3d\x01\x82\x0e\x50\x40\x73\xbc\x90\x66\xc4\xec\x06\xcb\x84\x1f\x68\x72\x08\x09\x39\xd4\x2c\xf6\xe2\xba\x84\x49\xe8\x9b\x49\xe9\xfb\x72\x5e\x41\x40\xc6\xfa\xd4\x83\xd3\x04\x97\xd8\x03\x85\x8e\x23\xe8\x97\x05\xde\x78\xe8\x7e\x58\x97\xb5\x20\x65\x3c\x95\x85\x53\x48\xb8\x20\xdc\xa6\xb0\x93\x1e\x62\x05\x4c\x5a\x44\x0a\xc8\xfc\x0f\x1b\xce\xca\x21\xe7\x5f\xc2\xbb\xc7\x6d\x35\x7d\x28\xed\x61\xb6\x25\x40\x69\xf0\xd6\xb3\x9f\x67\xc6\x0b\xf8\x08\x79\xcc\x05\xdb\xe8\xd0\x5a\x73\x15\x9d\xdf\x55\x9e\xc3\x71\xb8\x6b\x08\xfb\xb7\x04\x88\xdd\xca\x42\xcd\xbc\x2d\xae\x06\x4f\x9d\x4f\x52\x80\xf0\xea\x77\x37\x78\xc3\x63\x2a\xba\x97\x52\x89\x2d\x7d\x9c\x2d\x77\xf5\x5d\xcc\x23\xf5\x69\x5f\x15\x59\x39\x81\xf5\xd9\x64\xd2\xfb\xcd\x28\xde\xc0\xc2\xd1\xb6\xda\x8e\xae\x3d\x4d\x8b\xa2\x30\x57\x33\xa8\x2f\x30\x4d\x6d\x2d\x23\xc2\x60\x4b\xcd\x48\x86\xef\x3f\xb6\x4a\x4b\x3b\xb9\x48\x15\xe2\xf1\xa7\xa0\x97\x87\x4e\xc9\xea\x06\xb6\xf0\x18\xea\x37\x0b\xb9\xd3\xe9\x0a\x9e\x08\xc7\xea\xbb\x2c\xb7\x1a\x07\x85\x68\x12\x9e\xd0\x7c\xcc\x2a\xca\xe5\x14\x94\x1a\xeb\x1f\x95\xef\xd4\xfc\x76\xe6\x0f\xc6\xb3\xaa\xc3\xab\x8c\x8f\x16\x08\x43\xfc\x48\x4b\xfa\xf0\x5c\x66\x45\x0f\xfc\xd9\x3b\xb9\x2e\xf6\x21\x9a\xc5\xdb\x1c\x22\x4f\x3b\x21\x67\x0b\xab\xad\xb8\x25\xa7\x51\xe4\x89\x06\x99\x96\xaa\x37\x25\x3b\xb4\x62\xdd\xdd\x31\x2b\xe2\x10\xd0\x33\x67\x93\x10\x04\x54\x8e\xe0\x79\x71\x94\x77\x43\x1e\x19\x70\x0d\x00\x3b\x82\x2f\x98\xf6\x7d\xc3\x55\xfe\x5a\xde\x31\x53\x92\x11\xa5\x1f\x9f\x6d\x2e\x5d\xae\x5b\xf7\xf0\x6b\x9b\x4b\xf6\x41\x82\xb1\xcb\x49\xfa\x92\x1a\x3b\x71\x2b\xf4\x42\x5d\x57\x95\xc1\x24\xd1\x16\xd9\x4c\x07\xbd\x43\xa7\x58\xc5\xc4\x91\x45\x6d\x8f\x89\xea\x75\x05\x3d\x97\x65\x15\x52\x4d\xf3\x34\x69\xce\x62\x81\x42\xed\xaf\x83\xfe\xd0\x69\x40\xbe\xfc\xc9\x2a\x6d\xa5\xfc\x3d\x9f\x76\xca\xe2\x21\xde\x07\xc7\x04\x0e\xeb\x75\x89\x22\xc0\x96\x39\xa1\x48\x87\x60\x1f\x1a\xd2\x18\x68\xd3\x4e\x4d\x55\xa0\xef\xea\x92\xae\xdb\x03\x05\x9d\x2c\x41\x1f\xd4\xcd\x89\x19\xef\xbc\x23\x43\x0e\xa2\x59\x5e\xac\x1b\xb9\xcf\x7c\x28\x4b\x53\xfe\x68\x4a\xc4\xf4\x14\x28\x09\x03\x18\x5f\x11\x42\x49\x0e\x9c\x2c\x4b\x30\xa3\x08\x04\x79\x45\xfa\xae\xf5\x4c\xfb\xc1\x60\xf5\x01\xe9\x97\x4d\xb4\x15\xc3\xc6\x76\x10\x49\xb5\x7e\x94\xa2\x6f\x71\x02\x28\x28\x58\xc2\x8b\x29\x74\x6d\xde\x3a\x57\x34\xd4\x0b\x26\x7e\xd2\x3c\x45\x3d\x3c\xe3\x2e\x19\xe0\x3d\xe8\x75\xcc\xa6\x83\x8f\x48\xa3\xba\xf6\x96\xa6\x6b\x25\x64\xd7\x3f\x04\x07\x9c\x2b\xeb\x23\xf4\xf8\xfe\x5e\x39\x6e\x3f\x06\xc1\xe9\x81\x75\xfb\xbb\xea\x42\xce\x41\xcf\x13\x85\x5e\x7d\x00\x77\x20\xba\xbb\x32\xf4\x1a\xdb\x46\x13\xdc\x36\xdc\xc9\xed\xe3\xb7\xcf\xb9\x28\xdd\x2d\x74\x18\xab\xcb\x4c\x3c\x57\xa0\x56\xd2\xe3\x18\x5e\xb0\x32\x03\xcb\xcc\x95\xad\x07\x96\x65\x1f\x15\xf2\xae\x2b\x79\xe5\x00\x65\xe5\x27\xab\x17\x16\x40\xeb\x11\xb4\xfc\x51\x60\x65\x9e\x6c\x15\xeb\xd5\x79\xb0\x24\xb5\x79\xa2\x3a\x54\xba\x5e\x29\xd6\x3a\xd5\xbd\x1d\xd6\xe5\xfd\xba\xa2\x80\x1f\x36\x0a\xd9\x43\xda\x2e\xce\x26\x8a\xfe\x29\x94\x3b\x30\xec\x1d\x21\x95\xc2\x69\x22\x6a\x45\xc4\xdb\xe7\x77\x3f\xda\xa3\x72\x2c\x7c\x13\xa6\x44\xfd\x2b\x2e\x63\x70\xef\xee\x2e\x87\x32\xfb\x88\x83\x8e\xb4\x79\x68\xa0\x05\x14\x9e\x92\xaa\xf8\x4d\x85\x43\x4e\x10\xf9\x5a\xed\x9e\xca\xe8\xca\x3a\x82\x06\xce\xcb\xc1\xa6\x34\x4e\x81\xa2\x40\x49\xe4\xf7\x21\x57\xa3\xfb\x9d\xd3\x2f\x34\xb8\x62\x60\x37\x1c\xe0\x66\xa5\xde\x98\xaf\x90\x21\x8f\xda\x62\x13\x7f\x6b\xf8\xdb\x3f\x7d\x48\x55\x1d\xe1\x2e\xcc\x64\xbe\xec\x7c\x93\xf3\x1b\x7f\xcc\x0f\xf7\x51\xe3\xfb\xe0\x0a\xc9\x05\xf3\x81\xc4\xf5\x07\x0b\x54\xfe\x1d\x0b\xff\x4c\xf9\xbe\xc6\x73\x2a\x2d\xae\xac\x1e\x0f\xf4\x29\x45\x20\x0b\x8b\x64\xe3\xcb\x0b\x53\xe3\x69\xf4\xbf\xd3\x33\x48\x98\x9a\x41\xdc\x95\xf8\xa9\x21\x21\x49\x48\x79\xdc\xe8\x46\x6d\x0a\x1f\x5f\x79\x7f\xda\xeb\x0d\x07\x83\xf4\x24\xc3\xd4\x4c\xc9\x97\xb6\xd7\x86\xce\xde\xff\xc1\x6a\x37\xdf\xf7\x3f\x57\x0e\xf6\xff\xe0\x8a\xfb\xe3\xf2\x07\xde\x06\x4f\x8c\x9b\x59\x6d\x00\x1d\x5a\x55\x55\xff\x0a\x47\xf9\xe9\xe2\xe9\xb0\x8f\xfc\x44\xb4\xeb\x6f\x4b\x27\x91\x76\xfc\xf0\x7c\x16\x58\xd8\xda\xe7\x8e\x4f\x75\x35\x39\xd8\x55\x48\xbd\x42\x1c\xbb\xcc\x85\x58\x11\x61\x5e\xe0\x2a\x5b\xc4\x34\x19\x57\x8c\x5c\x9f\x38\x3f\xe3\x4d\x08\xf2\x43\x3e\x47\xc0\x2f\x07\x8f\xaf\xe8\xfb\xac\x4d\xf7\xd9\xb7\xc2\xc9\x8c\xa1\x3e\x13\x08\xaa\xc5\x31\x27\xac\xe9\xcd\xa2\xb2\xac\x08\x84\x07\x09\x1c\xaa\x56\x6b\x8b\xef\x88\xb0\xd1\x80\x3b\x4d\x14\xa1\x4d\xd5\x78\x43\xe6\xc9\xa1\x0d\x97\xe2\xbb\x2d\x42\xba\x56\x65\x3d\xbb\xf1\x3a\x0b\xc1\x47\x33\x21\x26\xc3\xfe\x27\x24\xbb\xc9\x1c\xea\xb2\x14\x64\xcc\x72\xc6\x49\x10\x6c\x52\x5e\x05\x52\x57\x43\xe5\xf9\x42\xee\x37\x16\x54\x5a\x5a\x9b\xb5\xb2\x43\x6d\x9d\xcb\x2c\xf5\x4d\x57\x25\x5a\x04\x79\x80\x17\xcd\x51\x2e\xa8\x25\x61\xe3\xfe\x0e\x62\xac\x6d\x5f\xf9\x66\xfc\x96\x7b\x24\x26\xc4\xad\x04\xb2\xaf\x45\x57\x04\x5a\x9b\x19\x0b\x5f\x7a\xf3\xed\xad\xd3\x58\xcd\xc2\xe2\xa5\xed\xeb\x00\x4f\xff\x16\xe5\x93\x35\x7e\xea\x1c\xf7\x54\xf6\xee\x24\x74\x65\xdd\x7d\xd6\x75\xca\x16\xe7\x16\xe4\x8d\xd6\xbc\x10\x07\x29\x01\x37\xcd\x4a\x3f\x3b\x14\xd9\x89\x04\xf0\x38\x44\x17\xba\xe7\x43\xc8\xed\x3e\xff\x4b\xa7\x70\x60\x53\x50\xab\x73\x07\x1a\x8c\x6a\xbe\x3c\xbe\xc5\x87\x5c\xee\xbf\x72\x9f\x74\xd0\x21\x9d\xc1\x80\x64\x43\x5c\x90\x06\xe5\xa4\x99\xdb\x79\x2c\x76\x2e\xfb\x6d\xd5\xd6\x71\xf5\xaf\xed\x1d\xda\x74\xe1\x70\x5e\xe7\x24\x3c\xd1\x9f\x4a\x38\xf7\x37\x98\x26\x1d\x70\xba\xae\x4b\x8d\x2c\x5e\xc2\xe0\x3c\x8a\xb0\xa9\x71\x08\x95\x0b\x24\xc7\x35\x8b\xb8\x5c\x83\x66\xbf\xc1\x53\x3a\xa3\xe2\x8d\x7d\x4b\x3f\x93\xd6\xe9\x1b\x27\xa1\xd1\x3a\x43\x80\x1c\x84\x69\xfe\x59\x68\xc4\xb5\xb5\xd3\x98\xed\x6d\xd3\xaf\xa2\x12\x5e\xb6\x1b\x2e\x68\xa5\x34\x51\xb7\xb4\x4c\x37\xf1\x07\xbf\x4e\xcd\xc8\xd5\x1e\xd0\xe4\x2d\x97\x87\x25\xe2\x02\xbd\x36\x85\xb1\xb1\xd8\x09\x55\x80\xe7\xbf\x52\xfd\xea\x1e\xc7\x79\x33\x7f\x80\xd5\x61\xef\xfc\x15\xa2\xbc\x25\x62\x66\x92\x6f\xd7\x0d\x8d\x43\x3b\xa6\x9b\x17\xf5\x56\xb5\x44\x56\x6e\x0c\xf6\x2c\x1e\x1d\xcd\xd6\xcb\xf6\xda\xd1\x6e\x19\x87\x04\x4e\x97\x13\xad\x8c\xb2\xcc\xaa\xa4\x7f\xa2\xd1\x1b\x0c\x64\x16\xc3\x4e\x68\xc6\x4b\xc7\xea\xe2\xaf\xbf\xe2\xf8\xb5\xe7\xc5\x10\x95\xc3\x2d\x54\xbf\x51\xdc\xef\x31\x85\xbb\x5f\xe6\x7e\x8f\xce\x7d\x8c\xd2\x24\x14\x26\x28\x9f\x03\x92\xda\xc0\x0c\x07\xe9\xfa\xa6\x7b\x9f\x37\x52\x3b\x75\x9e\xfd\xfe\x43\xeb\x6f\x91\x1e\x7f\xae\xdc\xaf\x82\xff\x55\x7f\x75\x1f\xfa\x59\xfc\x8f\xf7\xad\x12\x34\x52\xe8\x5c\x8e\x71\xa0\xdd\x1a\xd1\xe7\x36\xa9\x59\x1a\x69\x6c\xd2\x92\xe8\x2e\x5b\xef\xdd\xa5\x58\x04\x60\x2d\x32\xfc\x85\x20\xc0\xb8\x4e\xf9\xc6\xbe\x75\xcb\xa8\x4d\x07\x3d\x5d\xfb\x7c\x2d\x67\x81\x5c\xff\x84\x24\x83\x97\x01\xcb\x90\xef\x82\x73\x89\xe9\xf6\xd4\xf3\xcc\x14\x28\x29\x92\x32\xab\x2a\x17\x4b\x15\xd7\x1a\xaf\xbc\x84\x0b\x30\x95\x39\x91\x2c\xc9\xac\xb6\x0f\xdc\x07\x12\x57\x97\xb0\x6a\x9e\x49\x2b\x89\x21\xd2\x7e\xe0\x6c\x80\xba\x9b\xac\xf3\x64\x46\x3e\xd8\x43\x34\x8d\x0f\x95\xd1\xf0\x82\xbc\x0d\xf4\x6e\xc1\x96\xfe\x5a\xc7\xf6\xa3\xf7\x5c\x5b\xde\x1a\x5b\xb2\x43\x96\xf8\xad\x59\xcb\x0f\x05\xd2\x7b\xcc\x51\x6c\x92\x49\x81\xbf\x6e\x23\x6d\xed\x93\x91\x56\x2f\x77\x1f\xbd\x53\x9a\x31\x82\x40\x73\x5f\x7e\xcf\x46\x12\xa4\xf0\x84\xfc\x77\xeb\xed\xf4\xd0\x1f\x4f\xa3\x8f\x20\x2f\x93\xd9\x95\x85\xe4\xa9\x4b\x9c\x3d\x21\xea\xc3\xac\x85\x76\xe4\x19\x3e\xa3\xaf\xee\x75\xa3\xb3\xb5\x20\xc3\xa3\x50\x52\x76\x2d\x25\x1d\xc4\xa4\xe8\xdb\x08\x02\xa0\x5e\xa2\xe2\xcd\xb2\xa3\x9d\x16\x0b\x96\xd5\xd4\x71\x38\x00\xe3\x37\xf3\xd3\x56\xf0\xa9\x33\x97\x65\x22\xb5\x0c\x15\x11\x34\xbd\xa2\x7f\xc9\x3c\xf4\x0a\x0f\x61\x29\x67\x0c\x5d\xb1\x87\x23\x56\x1b\xc2\x19\x7d\x3c\x23\xab\x0c\x6c\x6d\x08\x6b\x89\x74\x02\x16\xbb\xa4\x94\x0e\xa8\x5e\x56\xca\xce\x46\x09\xbd\x1b\x31\x03\x8c\xc5\x07\xb7\x92\xb3\x89\x26\x0f\x83\x20\x7a\xae\xc8\x94\x9e\x8f\xb5\xe7\xc5\xe6\xd5\x48\xe5\x33\x0d\x9f\x7f\x89\x9c\xbf\x80\xc6\x62\x35\x0e\x73\x31\xfc\xed\x52\xc9\x42\x15\x8d\x7e\x53\x21\x6f\x92\xd9\x5d\x35\x1c\x65\xb4\xed\xb8\xd5\x7e\xbe\x54\xf4\xb0\xf0\xfa\xb5\xa0\x84\x31\x38\x88\x93\x21\x44\xef\x62\x1f\x42\xea\xab\x58\x8c\x96\x71\x26\x54\xd5\x88\x12\x81\xac\xaf\x93\xbf\x16\xca\x38\x3c\x54\x4b\xbc\xa3\x56\xd3\x52\x10\x5e\xcf\x05\xe8\x70\x8d\x5d\xa0\xf1\x1a\x4f\x87\x35\x04\x82\x23\x61\x7c\x8d\x20\x83\xa3\x07\xcc\x75\x2a\x09\x9f\xda\x76\x6c\x35\x6d\xb6\x73\x9b\x52\x11\x98\x52\x90\x05\xb3\x0a\xce\xce\xf5\xe3\x13\xd9\xe4\x1c\x3d\xd7\x27\xbc\x08\x3c\xa7\xe9\x9b\xbd\xb3\xcb\xc9\x10\xb7\x8e\x1f\xfb\x8f\xad\xc1\xc5\x58\xff\xb9\xf2\x70\xa2\xfe\x71\xc4\xbd\xfd\x7b\x1e\x52\x43\xdf\xa3\xc4\x1b\x7a\xee\xc1\x8e\x87\xd1\x08\x6e\xf8\xcc\x3b\xcc\x47\x41\xe3\xee\x4e\x9e\xee\xe7\x13\x07\x10\x16\x90\x76\x85\x72\x35\x07\xd2\x17\xab\x62\x7c\xf0\x9b\x05\x99\x68\x7d\x66\x1d\x59\xa3\xe0\xae\x65\x59\xe1\x31\x74\xdd\x8f\xff\x5e\xe4\xb2\xcc\x45\x10\x56\xe0\xe4\x8c\xca\x01\x91\x69\xba\xce\x32\x2a\x63\xbf\xde\x98\x50\xfa\x81\x14\x68\xf0\x44\x8f\x31\xaa\x33\x9d\x4e\x5e\x09\xf0\x5a\x4c\xa3\xb2\x52\x5c\x29\x50\x87\x0d\xc0\xed\x7e\xea\xfb\x13\x89\xa1\xd4\x80\xe9\x6f\xe4\x83\xdd\x52\x5c\x19\xab\x5c\x1f\x31\x2d\xbe\x83\xa9\x9f\x2c\x0f\x06\x4a\x39\xd1\x07\xa9\xeb\xc7\xdb\x9d\x5c\x26\x2e\xa8\x61\x31\x88\xdc\x96\xd8\x70\x8f\xac\x83\x2d\x48\x13\x55\x12\xd6\x81\x08\x1d\x18\x9f\x8a\x50\xe2\xa7\x90\x22\xea\x64\x7d\x59\x5b\x32\x6a\x07\x46\xda\xf1\x7d\x51\xbf\xb1\xa2\x57\x56\xe6\xa1\x9d\x5e\xeb\x73\x64\x04\xd9\x13\xed\x6f\xf1\xe3\xe6\x14\x20\xb5\x72\x52\xe2\x4e\xb9\x37\x8a\xa2\x79\x58\x82\x6d\x6f\x40\xe8\xa8\x5d\x8d\xdb\x30\x19\xb8\xfd\x64\xfe\xf9\x12\xeb\xf6\x74\xd5\xe6\xd6\x17\xe3\xdd\x29\xb8\x63\xe6\x58\x1b\x0b\xa6\x5f\xb7\x02\x55\x9f\x9b\x10\x54\xd3\xeb\xec\x13\x0c\xc4\x7b\x6a\x5f\x85\xd9\xc9\x7a\x9d\x17\x97\x2b\x36\xf3\x2e\x9d\x9e\xe5\x93\x7b\x6e\x1e\x01\x09\xcd\x86\xc2\x08\xc5\xb6\xab\x25\x6a\x23\x15\x1b\x4e\x00\xe0\x1d\x42\x25\x54\xd4\x5d\x3c\x23\x3b\xcb\x47\xd1\x9b\xc5\x07\xc3\x05\xae\xa4\x2d\x70\xb9\x23\xf2\xb2\xcb\x9a\x0b\xa3\x39\x0a\x0f\x3d\x53\xe3\xdc\xe7\x74\xb5\xf3\xb1\x5c\x02\x3e\x1b\x24\x1a\x8e\x72\xdf\x71\x1b\xd6\xdf\x01\x34\xb1\x9e\xde\x43\x79\x42\x01\x72\x67\xbd\x07\xf4\x7e\xbb\x99\x39\x21\x8b\x0a\xfd\xe1\xa4\x03\xda\x69\xff\x63\xe8\xe1\x41\x9a\x95\x76\x2d\x91\x51\x9c\x68\x89\xcc\x0b\x23\x8b\xfe\x43\x4a\xba\xb6\x67\x73\x44\x9b\xb7\xc3\x08\xa3\x4e\x46\x48\x97\xae\x85\x19\x55\xdc\x2e\xfc\xa2\x06\x39\xba\xa6\x72\xa7\x6f\xda\x9c\x71\xb9\x54\x55\x8a\x72\xfe\x65\xc5\x33\x3a\x30\x77\x84\x1c\xe7\x3f\x03\xf6\x93\x12\xc0\x96\xbc\x77\xe7\x90\xa8\xb0\x4d\x0a\x13\xab\x0b\xc2\xd3\x52\xcc\xe9\x82\xd9\x62\x84\x6d\x5a\x72\xb8\x4d\x84\xc0\x49\x3b\x8c\x08\x05\x5b\x7f\x51\xf8\x06\xee\x53\xa7\x5d\x6b\x46\xda\xcb\x88\x70\xf3\x9d\x9b\xa3\x06\xd4\x30\x1e\x84\xec\x1a\x7d\xdf\xcd\xb8\xd4\x18\x6f\x37\xab\x00\x5c\x47\xce\xae\xf2\x18\x91\xc8\x3c\x3c\x1f\x3f\x28\xf9\x55\x1f\xe4\x97\x28\xcd\x04\x37\x62\xe8\xdd\x14\xfe\xd0\x4d\x9e\x1a\xb2\xf3\xe2\xf7\x9e\xbd\x1a\xe1\x4d\x61\x31\x75\x74\x8c\x8c\x4a\xa2\x2c\xdb\xaf\xc4\x61\xa3\x6f\xc6\xdc\x11\x99\x1c\xba\xec\x38\xf5\xb0\x71\xc2\x4f\x96\xad\xad\x9f\x00\x31\x8f\xf3\x5a\x0e\xf9\xf9\xce\x12\x00\x5a\x19\x04\x41\x41\x54\xd6\x69\x8e\x77\xbb\x35\x9b\xa4\x4c\x82\xfe\xe0\xc9\x56\x31\xff\xc9\xfa\x52\xcb\xf2\x77\x7e\x10\x94\x25\xf0\x7f\xf3\xd1\x08\x75\x25\x27\x41\xd4\x04\x37\xf7\xb9\x05\xa1\x0c\xe3\xfa\x63\xcb\xab\xac\xcb\x3e\x3b\xc1\xb7\x10\xa4\xd0\xb1\x09\x1b\x83\xa7\xbe\xfa\x16\x01\xac\xd2\xa4\xe2\x3d\x2f\xae\x0d\x15\xfa\x21\xf0\x7b\xc6\x39\x4c\xdd\x26\xbc\x2d\x0b\xa8\x2c\xe5\x35\x00\x1f\x70\x42\x96\x09\x66\x73\xc3\xa4\xff\xc6\x84\x02\x48\x8a\x40\xae\xaa\x24\x0d\xde\x57\xe8\xad\x72\x8d\xe6\xb3\x44\x28\x90\xab\x52\x6e\x39\xc7\xe5\xfa\xfb\x97\x87\xc1\x81\x18\xe4\xd6\x88\xb8\x5b\xb8\x26\x2c\x5e\x13\x59\x54\xe7\x59\xae\xc9\x7d\x1a\xc9\xda\x23\xca\x53\x13\xad\x91\xcb\x15\x93\xd5\x11\x87\x27\x2c\x79\x62\x6b\x55\x7d\x11\x59\xce\x71\xf9\x72\x0f\x4b\x10\xe7\x5b\xab\x4d\x3e\x9f\xf3\x55\x07\xbe\xdd\xfd\x24\x34\x66\xe0\xf9\x32\x4e\x8e\x02\x0e\xcf\xf3\xa1\x4f\x0f\x98\x51\x04\x01\x96\xa4\xe5\xb8\x21\x05\x04\xff\x71\x1a\xf8\xf2\x98\x34\xd1\x9c\x1a\x0f\x41\x51\xe3\x3a\x47\x8f\x21\x91\x9f\x1f\x16\x8a\xe7\x0d\x58\x7b\xc8\xc5\x22\x7d\x65\x1a\xc9\xb3\x82\x7f\xa0\x2a\x01\xd2\x52\x01\xca\x54\x4e\x30\x5a\xfa\xb4\x13\x07\x6b\x05\x96\xcc\x44\x4d\x90\x8e\x76\x3a\xcd\xc0\xb8\x70\xbe\x84\x99\x58\xb9\x47\xd5\x54\x37\xcb\x2f\x2a\x34\xf9\x1d\x9b\x85\xa7\xb8\x6b\x79\xeb\x9a\xbc\x66\x35\xfd\x0a\xc6\x75\x11\x23\x03\x2e\xed\x5a\xe5\xe4\x5a\x5c\x01\x8b\x64\x64\x12\xa4\xb4\x35\x6f\xf5\x1a\xfd\xea\x7b\xcb\x2b\x84\xb1\xad\xf6\xa7\xff\x5a\xe2\x7e\x9b\x59\x4f\x56\xb3\xb9\xec\x1d\x4f\xa0\xf9\x8a\xea\x82\x56\x68\xd6\x99\xcf\x81\xaf\x31\xc9\xbc\x37\x73\x9b\xd5\x1e\xfa\xcc\x18\x66\xb8\x23\x58\x3c\x01\x62\x7d\xbc\xd7\x7a\x5b\x89\x52\x80\x31\xf8\x59\x84\x06\xdd\xdd\x19\x46\xb5\xa3\xd0\xb0\xfb\x63\x9c\xc5\x3c\x8d\x4b\x37\xb5\x59\x39\x08\xcd\xcb\x8f\x6d\xba\x0d\x13\xc1\x3e\x7a\x6c\x74\xf5\xd9\xfd\x78\x59\x3b\x98\xcd\xab\xf8\xfc\x6a\x59\x2c\xbb\x83\xdb\x1e\xe7\x86\xc2\x6f\x1a\x6a\x73\xac\x60\x30\x62\xaa\xcb\x39\xf5\x64\x8b\x2d\x32\x04\xfd\x38\xd9\x8b\x0d\xcd\x34\xe5\x32\x70\xf7\x10\x28\x6c\x16\x20\x00\xc3\x0d\x1f\xbc\x53\xd0\x23\x06\xb7\xd0\x08\x08\xab\xca\xc5\x0b\x3a\x98\xd9\xf2\x74\x42\x47\x4b\x55\x09\xea\x07\x16\x3c\x9e\x3a\x51\xdb\x72\xf1\x07\xe8\xa5\xaf\xba\xc1\xd1\xa4\xbb\x74\x0b\xe1\x46\x11\x91\xe6\x25\x3f\x39\x2f\xef\xf2\x8c\x01\xcb\x39\x1c\x5e\x2f\xbe\xac\xfb\xf2\x02\x0b\x99\xd5\x62\xf0\xa7\x74\x44\x5f\x17\x9d\x4f\xea\xc2\x4b\x1f\x1f\x9b\x38\x5a\x53\xf8\x29\x8c\x81\x0b\xad\x57\xe0\xee\x4b\x39\xa7\x90\x49\x4b\x44\xe8\xba\xbe\x9a\x1c\x44\x92\x72\x0b\xcc\x0b\x66\xfa\xb4\x49\x74\x6f\xe9\x88\x15\x73\x6f\x02\xc9\xd6\xe4\x18\x9d\x9c\x86\x4e\xa5\x1e\x7d\xb5\x70\x37\x77\xf2\x01\x4d\x45\xa4\x54\x81\xbd\x27\x92\xe0\x9c\x67\x75\x81\x2d\xc7\x54\x4f\x94\x9b\x49\xc4\x38\xa2\x5d\x39\xc9\x6f\x7c\xf9\xae\xb8\x92\xea\x78\x59\x75\x69\x8b\x5e\x7f\x65\x0c\x23\x43\x1c\x6f\xad\x96\xda\xb7\x7f\x38\x63\x8e\xe7\xcf\x05\x99\xa9\xf8\xff\x8b\x14\xcf\xfa\x94\x1e\x7a\x81\xb0\xd1\xdd\x23\x84\xd7\x22\x08\x1f\x3f\xe0\x6d\x5f\x80\x64\x00\xe5\x35\xbb\x65\x89\xe1\x43\x0d\xea\x83\x3c\xa0\x11\xa9\x7b\x2b\x12\xd5\xaf\xb5\xf5\x1c\x9a\x2d\x73\xd3\xfa\xc7\xaa\x8b\x07\xd5\x84\xb3\xc4\xdd\x9a\x8c\x55\x35\x94\x98\xc1\xab\x85\x2e\x0d\x5f\x75\x5d\xd1\x65\x59\x55\x95\x9b\x68\xea\xf3\xd3\x4c\x55\x48\x70\xa0\x85\xb7\x00\x4c\x64\x96\x40\xc5\x40\x27\x68\x64\xc1\x72\x11\x0d\x49\x19\xfe\xaf\xfb\x79\xac\x4e\x4a\x04\xf0\xc4\xd4\xad\xdc\x96\x94\xe8\x99\xd9\x39\x69\xa1\xd1\x17\x0f\xc2\xb5\x37\x2b\x5e\xeb\x59\x0f\x49\xf5\x80\x39\x04\x05\xa8\x79\x00\xe4\x59\xb2\xb5\x98\xa0\xfb\xbd\x76\x8f\x42\x0f\xab\x3f\x8c\x9b\x50\x09\xc2\xce\xf4\x83\x71\x66\x57\x4a\x1e\xe1\x66\x3c\x14\xb9\xcb\x77\xa7\xa4\x19\x32\x54\x27\x1b\xbc\x36\x0f\x76\x4d\xd2\x0e\xc4\xd7\xbe\x3a\xfd\x2c\x79\x90\xc3\xa5\xf7\x0f\x34\xb7\x8c\xa7\xf7\x4c\xff\x07\x1f\xdb\x4e\x2e\x14\xe6\xb4\x74\xb4\xac\xe9\x77\xac\xf3\x49\xae\xb8\xab\xda\x8a\x32\x26\xee\x2a\xde\xfb\x5c\x08\xbb\xac\xf4\xbf\x3e\x7f\xb5\xf8\x22\xe4\x32\xad\x72\xed\x41\x25\xdf\xe8\x05\x01\xed\x04\x8f\x7f\xf4\x04\x62\x28\x6e\xab\x38\x54\xf2\xf9\x73\x8f\x9b\x70\x47\x45\x8b\x57\x6a\xec\x1e\x5e\xf0\x60\x62\x47\x36\x4b\xae\x59\xf8\x7b\x70\x11\xf4\xc9\xdf\xb4\x2b\xec\x0d\xf1\x6f\xd3\x83\xf5\x41\x31\x79\xc6\x39\x45\x43\x0a\x17\x8a\xb6\x9d\x20\xe2\x2a\xbb\x15\x02\xd0\xc7\x44\xc6\x6d\x6d\x6c\xc1\xa7\x9a\xe1\x53\xec\x43\xaa\x56\x6e\x58\xbc\xc6\x65\x9d\x63\x6e\xb3\x98\x25\xab\x8f\x27\xc9\x0a\xde\xc6\x80\x0e\x81\xe0\x51\xdb\x5d\x36\x0a\x65\x79\x53\xe5\xb5\xaa\x5a\x81\x97\x62\x56\x80\x63\x15\x62\x0b\x99\xd9\xb6\x99\x20\xb3\x1c\xd8\xc4\x45\xd4\x1c\x76\x8d\x76\x15\xfd\x60\x93\xca\x5e\x47\xc8\xb0\x30\x39\x08\xa7\x74\x2c\xe8\xde\x7f\xb2\xf7\x94\xe3\x83\x23\xee\xb0\xac\x33\x28\xa6\x3f\x3a\xd0\xfb\x5e\xc6\x8d\xdb\xd2\xa9\x87\xbf\xa5\x61\x7e\x39\x91\x1e\x7b\x82\x56\x5d\x6a\xa3\x5d\x48\x50\xcd\xe2\xac\xb3\xb8\xa4\x25\xeb\x24\x4c\x8b\xd7\x01\x3d\x26\x56\xa4\x91\xd5\xd5\x13\x6c\x69\x64\x91\x28\x37\x8d\x1c\xac\x9e\xa2\xd2\xb9\xad\x07\xcb\x1b\x2c\x8b\xef\x6d\xae\xcb\x1b\x19\xba\x28\xe6\x3c\x70\x56\x09\x11\xb6\xb4\x49\x4f\x0c\x5f\x97\x84\x6b\x66\x02\xb0\x26\xaf\x8e\xaa\xaa\x05\xeb\x4c\x8a\x47\x8d\xbf\x2c\x57\xb6\x99\x05\x53\x7c\x1c\xde\xe3\xef\x87\x88\x38\x44\x7d\x2a\x13\x5d\xb3\xa9\x17\xf1\x04\x7f\xf5\x48\x44\x35\xac\x07\xba\x06\xa2\xfc\x89\x9c\x56\xfd\x34\x3d\x5c\x47\xa3\x31\x90\x17\xd8\xc2\x4b\x1e\x79\x16\x79\xa8\x85\xc7\xe7\x59\xa8\x25\x2b\x67\x47\xf7\x09\x0e\xf8\x52\xdd\x19\x3f\xb9\xe2\xee\x51\x42\x48\xd3\xe8\x58\x48\x17\x0c\x52\xb1\x82\xfe\xb1\x0d\x86\xfb\x4f\x66\x6c\x66\xe1\x1f\x98\x71\x58\x3c\xcc\xfb\x56\x65\xd6\x10\x84\x37\x1c\xba\xd9\x0d\x19\xd6\x19\xeb\xde\xbd\x5a\x67\x02\x3c\xdf\x67\x97\xb2\xad\xbd\x47\xcf\x12\x01\x1c\xae\x8f\xd9\x11\xf1\xbb\xc4\x6a\xa3\x4c\x67\x3c\x6e\x68\x33\x19\x0f\xa2\xfc\x38\xbc\xbc\x37\xf2\x1a\x0c\xc0\x68\xe3\x1d\x09\x7e\x42\xc0\x66\xa8\x7f\x9c\xc9\x99\x12\x14\x86\x11\xc4\x36\x20\x02\xcb\xf3\x18\x33\x10\xd4\x65\x15\x98\x26\xc5\xad\x69\x11\xb9\xf4\xa3\xfd\xb0\x25\xb1\xf7\x18\xaf\x21\xdd\x7f\x99\x42\xf1\xd8\xf6\x32\xd3\x21\x21\xcc\x72\x5a\x60\x44\xb5\xc4\x7c\xf5\xc3\x79\xb6\x3c\x69\x50\x2e\x57\x2e\xa9\xb6\xb0\xb9\xc3\xb2\x6b\x0a\x06\x1c\x9b\xea\xa7\xdc\xb9\xa1\x05\x63\xfe\x32\xe0\x13\x60\x73\x33\xfb\xe1\x71\x43\xa8\xea\xd7\x20\xbb\x0c\x6b\xa7\xdf\x8e\xd6\xe1\x38\x6f\xba\xce\x45\x07\xe9\xdc\x30\xc7\xad\xec\xb9\x5e\x0b\x8c\x12\x4c\x85\x27\x44\xfb\x15\xc5\xee\x89\xa5\xcc\x21\x96\x7f\xca\x80\x92\xda\xc8\xe6\x58\x2f\xab\x33\x46\x0f\x38\xc1\x50\xb5\x2f\xc6\xcf\x76\x4e\x00\x66\x4c\xfa\x20\x24\x80\xa8\xb6\x36\xcd\x75\x70\x4a\xd0\xeb\xb9\x97\x9a\x7c\x75\xfa\x85\xa9\x7a\xea\x32\x27\xba\x87\x41\xbb\x01\x48\x4b\x06\x72\xa0\xc6\x6e\xf6\x42\xbe\x57\x08\x3e\x99\x4c\x27\x49\xc7\x8c\x64\xd7\x81\xa9\xf0\x06\x76\x9a\x51\x8b\xfa\x7b\x91\xde\xb7\x0f\x09\x6e\x85\x7b\xa9\x3b\xbf\x37\xce\x39\xd7\xd9\x5b\x7d\x2d\x86\x0b\xa7\xbe\xa8\x40\xa6\x48\x27\x8f\xec\xb6\x0a\x9c\x30\xe1\x5b\xa3\x5a\x0e\x1a\x88\x53\x73\x99\x1e\x1d\x23\xa1\x96\x77\x6d\x95\xdb\xf4\xbe\x3a\x55\xe3\xe7\xa0\xb8\xfe\x74\xd5\xc8\x98\x86\x9a\x64\x5a\xe7\x3a\x7e\x59\xe6\xfc\xd9\x29\x89\xd5\xfb\xa3\x12\x3d\xf6\xb6\xc0\xd9\x64\x7a\x5f\x35\x7a\x70\x15\x90\x85\x8b\x59\x5c\x3d\x7a\xd2\xa9\xc2\xef\x4d\xd3\x59\xdd\xd6\x82\x4b\x19\xee\x7e\x53\x32\xfc\x8d\x10\xc8\x5a\xac\x83\xf4\xc2\x4b\xb0\xf9\x34\x86\xb6\xe3\x2b\x6b\xee\x28\x82\xaf\x1e\xde\x64\xb1\xa5\x43\xfc\xb4\x7b\x2e\x63\x81\x82\xd9\xf8\x0d\x26\x56\x48\x16\xd6\xdb\x9c\x83\xbd\xb0\x63\x86\xdd\x83\x74\xcd\x4d\x7d\x5a\x6b\xe5\x79\x1a\xad\xfa\xd8\x03\x46\x19\xda\x8a\xb9\xf4\x5b\xe9\x17\x25\xc1\x69\x5b\xcb\x2e\xab\xeb\x0d\xdb\x63\xd5\x56\xde\x3e\x99\x34\xd3\x86\xaf\x3b\x48\xd4\xe9\x43\x52\x03\xeb\x6b\xb7\x27\x01\xa6\x1d\x8b\xe5\xce\x62\x69\x50\x9b\x3a\x35\x4c\x44\x94\xcd\x6c\xba\x9a\x2c\x5b\xd5\x24\x9a\x46\x24\xea\x7a\x68\x10\x8f\x5f\x05\x43\x11\x73\x59\xa7\x23\xe3\xd6\x60\x12\xcb\xd5\xee\x8f\xe0\x1a\xa9\xe6\xec\x5c\xf6\x81\x28\x63\x9e\x89\xf3\xa6\xdf\xf3\xf3\x4f\x3b\x57\xa8\xf6\x22\x06\xcc\xc6\xca\xdf\xa7\x89\x5b\x4b\xc1\x3c\xa7\x08\xd3\x4c\xd7\xd2\x91\x57\x1b\x7e\x67\x59\x10\xf9\xeb\xfa\xa3\x10\x00\xfa\x28\x62\x42\x7c\xe5\xf8\x01\x05\xf6\x9b\x88\x54\xba\x79\x91\xa6\xa5\x48\x99\xe9\x33\x31\x86\xef\x8f\x1c\xb7\x17\xcf\x9f\x6d\xfd\xf7\x1f\x77\xff\x8f\xbf\x6a\x8e\xd8\xaa\x0c\x7d\x3c\x8a\x59\x82\x7b\xce\x18\x95\x2c\x0d\x84\x3c\x65\x02\x61\xa1\x77\x87\xb7\x17\xe1\x8e\xa1\xec\x44\xa4\xce\x9e\xbc\xee\x37\x06\x05\x40\x1b\xf9\xc9\x22\xab\xdd\x3e\xe3\xf6\xe2\x3c\xd4\x87\x42\x20\xdb\x40\xa6\xbe\xf0\x91\x09\xca\x88\x94\xe3\x1b\x79\x67\x27\xe6\x29\x80\x72\xfd\xbd\x97\x45\xa5\x4d\x13\x62\x99\x05\x41\x9c\x2e\x4e\x6c\xf7\xef\x62\x09\xaa\xec\x89\x2a\xe1\xbf\xe5\x44\xe8\xd8\x5f\x5d\xea\x50\x6d\x31\xb1\xb4\x25\x45\x82\xc8\x82\x4e\x81\x1d\x15\x90\x3c\x28\x53\x63\x91\x15\x3c\x95\x2c\xdf\xb1\xac\x97\xdf\xec\x2a\xa4\x59\xdf\xdd\x4c\x53\x79\xc3\x19\x2f\x1f\x0e\x73\x63\xf2\x3a\x47\xe0\x08\x5d\xfb\x85\xa2\x6b\x29\x92\x8c\xef\x34\xaa\x3a\xa1\x4e\x87\x01\x67\x3d\x5a\x5c\x3e\x48\xcb\x8e\xd5\x72\xca\xcd\xcf\xde\x05\xf7\xd5\x1f\xdb\x44\xc5\x2b\x92\xa4\xdb\x54\xf0\x28\x74\x5f\x39\xef\xc9\x0b\x97\xec\x7d\xea\xe8\x47\xc8\x89\xcb\xeb\xe0\xe0\x66\x6a\x34\x15\x09\x32\x28\x18\xc9\x16\xd8\x1e\x28\xb2\x20\x7f\xf4\xe2\x2e\x2f\xaa\xf6\x5c\x9e\x45\x31\x6c\x97\x19\xf3\x84\x55\x6d\x9f\x15\xe1\x5b\xd3\xdd\xa2\xae\x8e\x2d\x39\x66\x88\xd7\x6f\x42\x83\x28\xba\xd3\x4d\x54\x13\x83\x60\xb7\x02\xb3\x2b\x8d\xf3\x40\x42\x5d\x18\x9d\x44\x73\xaa\x12\x7c\xa1\x13\x16\xf8\x2e\x7a\x7c\x1f\xab\xc1\xd9\x55\x75\xd5\x53\x82\xaf\x2b\x45\x41\xe8\x1c\x36\xd5\xa1\x3d\xe0\x85\x1f\x19\xcf\xae\xa6\xba\x58\xa6\x73\x99\x7d\x82\xf1\x0f\x47\x6c\x5b\xaf\x24\xaa\xa8\x75\xd6\x51\x05\xd4\x93\x9b\x70\x6f\xb9\xe2\xb9\x1e\x19\x47\xc9\x37\xf3\x96\x15\x4d\x0e\x9f\x51\x07\x0a\x73\x7f\x35\x75\x7b\x6d\x3a\x55\x96\x4e\xf9\x81\xf4\xb3\x89\x26\xe2\xae\x45\x72\x10\xbd\x9a\x28\xdb\xa7\x84\x4c\x8d\x2d\xad\xc4\x1b\x67\x4c\x5e\x01\x5e\x42\xbe\xf9\x96\x3f\xef\xad\x8e\x8b\xc5\x06\xa0\x4e\x18\xd2\x95\x14\xef\x5e\xdc\x07\x5d\x51\xa5\xf4\x7c\x35\x7d\x9a\x68\x76\x30\xa2\x21\x9c\x09\x40\x5a\x61\x1e\x14\xe4\xb9\xac\x26\xcd\x70\xa9\x56\x44\x70\x51\x88\x6e\x37\x2c\x74\xf7\x23\xa0\x4b\x5a\xb6\xe6\xf7\xb0\x00\xb9\x4e\xc2\xe4\xcd\x8d\x17\xc6\xa7\x37\xe8\x95\x96\xcf\x9d\x23\xd5\xb4\x60\x2c\xc5\x4d\xa6\x99\x8a\x06\xfa\xf2\xe8\xb7\xca\xb1\x0e\x3b\x72\x76\xe2\x2d\xa4\xb6\x12\x87\x31\xa0\xe8\xe9\x92\x08\x21\xbd\x27\x2e\xbc\x46\x48\x24\x74\x4b\x82\x19\xde\xcd\xca\x25\x80\xbb\xf4\x8c\x79\xb0\x5c\xac\x70\x4d\xc2\xa3\xb5\x93\xab\x46\x16\xbf\x13\xbd\x66\xac\x9e\x45\xcb\xbd\x04\x96\x90\xf1\x53\x0d\xa5\xaa\x22\x66\xf1\xa7\xfe\x16\xf4\x96\xcb\x5a\x1b\x72\xde\x1a\x8b\x03\xe0\xba\x28\xfb\xf2\xfd\x11\x06\xf6\x9d\x9c\xfb\x0e\xe8\x3b\xc4\x9b\x6e\x2d\x6b\x28\x39\x30\xf8\xe7\xc6\x6c\xc8\x2a\x57\x56\x42\xfe\x04\x53\x3e\xf7\x10\x52\xbd\xed\x88\xcc\xb7\x87\x14\xf5\x37\xd2\x99\x17\x5c\x0d\x14\xcc\x91\x0c\x53\xd3\x4a\xf9\xae\x4c\x43\x41\xbc\xf1\x07\x37\x5b\xcb\xe5\x4f\x36\xf0\x1c\x87\xbf\xaf\xf7\xfd\xaf\xf7\x89\x2a\x5d\x60\xf9\x80\xde\x8a\xd9\x5d\x79\x1a\x52\x03\x18\xc5\x7d\xa5\xf0\x15\x1d\xd6\x66\x58\x51\x41\x4a\xe8\xa2\x13\x39\x0f\x65\xf5\x8c\x0f\xe5\xa8\x7b\xde\xb6\xdd\xe6\x9f\x4c\x58\x68\xc1\x83\xbc\x78\x81\xd8\x84\x5c\x64\xba\x7d\xf5\x4a\xbf\x98\xe9\x1a\x61\x61\x4e\xa9\x33\x42\xb4\x9b\xc8\x29\x92\x22\xa8\x87\x20\x1a\x43\x87\x6e\xa7\x22\xce\xca\xda\x57\x22\x81\x5d\x3b\xbe\x61\x5b\xa1\x7b\xee\xb1\xd3\xc1\x4f\x52\x24\x94\xc9\xe6\x45\xea\x31\xd9\x7e\x58\x76\x02\x1f\xd9\xcb\x1a\xd3\xb3\xa5\xc3\x2a\x2d\x9e\x9d\x95\xaa\x77\x2d\x64\x34\x77\xcb\xda\x0e\xde\xb6\x47\x91\x1e\xde\x65\x63\xda\x6b\x6a\x1a\xdf\x86\x79\x7c\xf6\x23\x32\xa2\x49\x33\x66\xeb\x8f\x89\x7e\x88\xf0\xce\xcf\x29\x11\x0f\x3d\x64\xd7\xb2\xaa\x8e\xfa\xab\x3c\xc8\x0a\x33\xe7\xe6\x47\x8e\x7f\xdb\xf7\x67\x07\x35\x18\xfc\x44\x13\x82\x0f\xf3\x77\xa8\x1a\x1f\xc3\x96\xfc\x22\x2a\x4f\x0f\xa3\xe2\x70\x5a\x94\x41\x5e\x99\x68\xc0\x44\xd5\xa8\x2e\x0d\x9a\x82\x49\x32\x73\xc6\x93\xfb\x45\x2b\xc0\x0d\xf9\x6e\x6b\x3d\xc8\x51\xd2\xdc\xfc\xc2\x4d\xf6\xbb\xc1\xca\x97\x3d\x16\xed\xcf\x45\xb4\x70\x4e\x99\xe6\x52\xcb\x28\xd4\x6d\x96\xa3\x7f\x1c\xb5\x1c\xa4\x95\x46\xbc\xe3\x77\xb7\xd9\xf1\x89\x2d\x34\x89\xbd\x50\x1a\xfc\xf2\x4e\xbb\xc6\x0e\xdb\x5b\x07\xf8\x61\xe4\x5c\x7b\xe2\x2a\xd9\x1a\xff\x63\xb4\xda\x1f\x59\x3c\x12\x39\x8c\x1e\xda\x85\x91\x05\xb5\xcf\x9a\x74\x52\x25\x31\xd6\x18\x6e\xb5\xd1\x84\xe7\x20\x93\xce\x2a\x6d\x98\x49\x53\x7e\x6e\xf1\x6a\x82\xfa\xf5\xa4\x81\x46\x9e\x7e\x1e\x3b\x09\xac\xcb\x9a\xa9\x39\xdf\xd1\x2f\xbc\x4a\xb9\x8c\x49\x16\x03\x00\x0f\xa9\xf7\xe9\xa5\x2f\x3c\x1a\xb4\xee\x84\xb6\x9e\xe9\xb8\x0b\xff\xed\x62\x1a\x04\x12\x7d\x55\xa4\x4e\xab\x75\xaa\xbd\x40\xfc\x73\x0e\x58\xac\xf5\x54\xe6\xe1\x5f\x1a\xc8\xdd\xe4\x8e\x10\x27\x5a\xd5\xd8\x7c\x6f\x51\x42\x3e\xcd\xc3\x5c\x07\x2c\xc4\xb9\xa9\xac\x75\xf5\x49\x7f\x52\xa5\x22\x6b\xa6\xab\xfb\x53\x7f\x05\x8d\x3c\x13\x62\x2c\x33\xc8\xe3\xaa\x71\xd1\xcc\xf4\xaf\xdc\x22\x31\x50\xa3\xe5\x12\x9e\xe4\x2e\x98\x79\x9a\x38\x9c\xb4\x6c\x22\xe6\x6f\x1d\x35\xd1\xe7\xd6\xad\x27\x27\x9d\x98\x27\x89\x1a\x15\xe4\xfc\x03\xfa\xab\x1a\x27\x1a\x8a\x3f\x59\x91\x5f\x82\x00\x47\xc8\x64\xd7\xdd\xeb\x7b\xd6\x7b\x77\xd5\xea\x14\x11\xb9\x5a\xad\x6c\x71\x44\x1c\x91\x9e\x35\x71\x3f\x5c\x73\xbd\xec\xba\xa7\xcc\x75\x6b\x7c\xf6\x59\x50\x8f\x78\x5e\x70\xdf\x68\xb7\x58\xa3\xc2\x23\xc7\x4c\x69\xfd\xbe\x49\x8e\xa4\xf5\x37\xa5\x84\x59\xe9\x8a\x63\xe6\x2a\x99\xe2\x26\xa1\x77\x21\x31\x55\x5f\x52\x6c\x05\xd1\x7d\x1e\x4a\x33\x34\xdb\x20\x86\xb8\x37\x88\x98\x17\x7f\xa4\xe6\x28\x9f\x3f\xd9\x15\x06\xf3\x7f\x2e\x44\x40\x3d\x79\xfc\x6d\x28\xfa\x6c\x40\xf2\x5d\x8e\x62\xe2\xf0\xe0\xd3\x76\xaa\xca\x36\x24\x04\x8a\xd0\x31\x4c\x31\xcb\xfd\xc6\x71\xd2\x19\x29\x2d\x6a\x4c\xd2\x11\x01\x12\xdb\x85\x28\x44\xda\xa0\x3d\x4a\x9e\x93\xb2\x8e\x33\x37\xb2\xd2\x56\x75\xdb\x32\x32\xeb\xd9\x27\x4c\x8d\x52\x35\xe5\x84\x2e\xe5\x80\x3e\xf0\xac\x5a\x3c\xc9\x87\x51\xd8\x57\x01\x39\x81\x10\x13\x87\x67\xb3\x19\x7f\x8f\xa2\xb1\xb8\xd1\xdc\x65\x47\x94\x20\x8c\x4a\xbd\x49\x10\xd4\x4e\x88\xf8\xa8\x77\x39\x7f\x57\x6a\x02\xff\x00\xb0\x00\xca\x11\x70\xb2\xb4\x4e\x85\xf2\x82\xc9\x95\x5f\x92\xfb\x53\x6b\x24\xc9\xfb\x95\xb5\xa4\xdf\x54\xb9\x64\xe3\xe6\x72\xf1\x36\x4c\x89\x2b\xab\x27\x22\x56\xf5\x7a\x5e\xa9\x6d\xb7\xd0\x5c\x99\x5a\xbc\x14\xf8\xb4\x98\x5d\x0f\x91\x06\xbd\xa2\xb2\xab\x5c\x9e\x27\x31\xa1\x71\x32\x7d\x87\xd2\xe2\x56\xe5\x16\x32\x0d\xe0\x18\xe4\xd4\xa2\xfe\x3b\x04\xbc\x43\xea\x31\x6e\x49\x1d\x74\xba\x8b\xaf\x42\xcd\xf3\x55\xde\x18\xee\xfe\x31\xcd\xfc\x6d\x22\x5b\xb9\xe1\x68\xc7\xbf\x4f\x3b\xe2\xa0\xf4\xe2\x04\x17\xa5\x12\xff\x5c\x4a\x84\x74\x37\xc1\x46\x64\xd4\x55\xa6\xe3\x17\xdc\x60\xce\x4d\xe3\xa3\x15\x1d\x74\xb2\xc6\x5a\xd9\x48\x05\xbf\x57\x5e\x55\x58\xa8\xe3\x03\x48\xc6\x3d\xc9\x2f\x74\x90\x48\x23\xc3\xce\x25\xe2\x08\xa0\x09\xf4\x4e\x76\xec\x94\x5c\x4b\xae\x26\x7d\x2f\xb6\x7c\x2c\xf7\xf2\xc7\xed\xd1\xc9\x25\x20\x2a\xf2\x38\x0c\x49\x9a\x85\x03\xe4\x58\xa7\xad\x0e\xf0\x98\x8f\x42\xaa\xa4\xfd\xb0\x59\x0a\x50\xda\xfa\x55\x62\x31\xbc\x52\x22\xf7\x72\xd2\x6f\x32\x21\xbe\xcd\xa4\x52\x6c\x12\xbd\x00\xdd\xd6\xf8\xf2\x03\x24\x9b\x8e\x21\x08\xa1\x73\x81\xa4\x83\x43\x14\x2b\x2d\x14\xa9\xc8\x33\x51\x5d\x4b\xb0\x5c\x83\x42\xba\x7d\x66\x0f\xfd\x82\xd1\x92\x68\xce\x6d\xf5\x19\x69\x3e\x89\x06\x9f\xba\xe4\x42\xa1\xcb\x8c\x9a\x94\x10\x9a\xe8\xd5\x29\x82\xfa\x99\xcf\xad\xc2\x3b\xc1\x77\xa8\x1d\x31\xa9\xcd\xce\xb8\x10\xf2\x9b\xdd\x88\x25\x99\x44\xe1\x1c\xd5\x1c\x6e\x91\x0f\xa0\x40\x09\x44\x1d\x7a\xd1\x6e\xa6\x2d\xf3\xb7\x2f\x51\xf6\xe0\xbb\x21\x95\xdc\xef\x74\xe4\x58\xf4\xd9\x27\x70\x9d\x81\x3b\x7e\x15\x4b\x6e\xd5\x95\x73\xd3\x3e\x2a\x40\x61\xa6\x5a\x3d\xd3\x3b\x4e\x07\x5a\x62\x29\x0a\x11\x16\x0d\xdf\xfb\xaf\x47\x8a\xca\xc2\x54\x83\xcb\xe4\x81\xca\x79\xd7\xc2\x31\x37\x2c\x7e\xf6\x6a\x7b\x3f\xb3\x4e\x93\xd5\x37\x9b\x43\xb0\x7d\xcf\x57\xa7\xc0\x0b\x42\x63\xa9\x5f\xec\x17\x6b\x81\xba\x34\xc4\xbe\xaa\x71\x4f\xa3\xf4\xcf\xcd\xf9\xca\xc3\xf1\x6b\xc4\x7a\x16\x01\xe6\xaa\xc1\xa3\x0f\xa3\x04\x1b\xcb\x96\xfe\xe2\x51\x3b\x44\x74\x8c\x5e\xe6\x77\xde\x9a\x81\xa2\x19\x59\x9d\x84\xda\x28\x3c\xb3\x81\x8d\x5e\x11\xf1\xd0\xad\xa8\xd2\x61\x94\x63\x14\x6e\x8d\x53\xc6\xad\xf5\xbf\x32\x35\xfb\xf8\xba\xf2\xe8\xaf\x1e\x46\x0e\x0c\x09\xcf\xff\x5a\x13\xfa\x3f\x92\x27\xd5\x70\xfd\xb9\x78\x32\x1e\x7f\xf7\x30\xc3\xdf\xae\x3c\xf0\xad\x6c\xdf\xb5\xd8\x67\xa3\x62\x49\x59\xaa\x0e\x67\xd7\xab\xe9\x57\x68\xeb\xd6\x11\x63\x40\xed\xae\xf3\xf4\x36\x10\xa5\x51\x54\xb7\xc0\xfa\x01\x6b\x3d\xae\x6e\x79\x4f\x27\xc8\xe9\xe4\x4e\x6c\x15\x39\xa9\x5d\x59\x14\xe4\x39\x72\x39\xe8\x40\x12\xa4\x98\x0a\x02\xfa\x16\xd9\x4b\xbf\x33\x19\x95\xcf\xfa\xdb\x70\x77\x4c\x75\xde\xb6\xd9\x07\xe9\x1e\x9c\x72\x03\x24\x45\xd4\x50\x7f\xca\x63\x71\x6b\xf5\xb1\x90\x11\x46\x61\x6e\x46\x11\xd7\x7e\xe1\x1e\x8c\x9d\xb7\xb8\x8a\x1d\x27\x26\x32\xc5\x91\x1e\x10\x1c\x77\x22\x06\x30\x2b\x6a\xec\x28\x76\xfa\xd4\x91\xa6\x04\xb1\xbb\xe4\x58\xf2\xd2\x8a\xd5\xd2\x6a\x59\x5e\xb2\x14\x9e\xda\xf3\xc1\xe0\xb1\x06\x41\x6e\x1d\xf6\xd8\xad\x91\xf6\x3b\x4c\x62\xcc\x3f\x03\xe1\x14\x04\x60\x5e\x56\xab\x59\x46\x42\x1b\x53\xe0\x05\x22\xe7\x96\xcf\x62\x9d\xd7\x5c\xd2\x52\x13\x23\x37\x87\x2d\x0d\x91\xb2\x29\x44\xa2\xd4\xb1\x59\x8b\xaf\x43\x19\xd6\x77\x27\xa0\x83\x75\xbb\xb3\x88\xca\xa4\x27\x6b\x4c\x75\x69\x15\x30\xfb\x16\xce\xdc\xe0\x1e\x27\x03\x98\x39\x1c\xe3\xd3\x8f\x95\xe3\x57\xab\xec\x62\x10\xfd\x5c\xb1\xcb\x30\x94\xd1\xa1\xd1\x26\x7b\xf4\xd9\xb9\x59\xd6\xd3\x33\x7a\xa6\x35\x36\x39\xc2\x1a\x6f\x37\xb7\x90\x5f\x01\xb9\x2e\x58\xd2\x67\xf3\x1b\xb6\x79\x10\x16\x99\xb1\x0d\xfb\x86\x97\x55\x29\xd6\x9d\x1e\xe4\xbc\x64\x7e\xb4\xc2\xca\x7d\xcf\x83\x42\xb2\xf7\x11\x67\x07\x4e\x74\xe3\x72\x2c\xb5\x3c\x34\x31\x7c\x9e\x5a\x91\xeb\x5e\xca\x24\xde\x61\x6f\x47\x34\x8f\xa6\x39\xdd\x64\x8f\xa5\x2b\x8b\x59\x48\x77\x39\xeb\x4d\x4e\x65\xb0\x40\x7e\xb7\xda\x7e\x59\x31\xbc\x96\x16\x48\x84\xad\xd5\x80\xa2\x32\xf1\x37\xcf\xdb\xf3\x75\x1f\x32\x3b\x9f\x3f\x7b\x73\xca\xdf\x94\xfa\x9a\x64\x64\x87\x18\xcd\x63\xdd\x26\x78\x38\x9d\xd1\x71\x10\x18\x0f\x9b\x40\x6a\x8a\xb8\x33\xc0\xb9\x1e\x3d\x73\x6d\xd9\x61\xef\xed\xbd\x6e\x36\xec\x3f\x93\xe7\xe6\xac\x11\x06\x3d\x8f\x9e\x4d\xba\x01\x3a\x93\x0d\xbe\x33\xa2\x3a\x23\x5e\x9c\x99\x0a\xad\xe9\xc9\xdc\xe9\x25\x29\xe3\x88\x1a\xad\xf9\xa6\x55\x84\x67\x2f\x9a\x8d\x5b\xd3\x74\x64\x52\x4e\x55\xcb\x4d\x14\x5d\xf5\xb6\x64\xaa\x77\x28\x3e\x61\x53\x83\xc6\xce\x8c\x27\x68\x6c\x27\x65\xa1\xd9\xb7\xc7\xee\x6b\xa5\x49\xe6\x14\x84\xf0\x87\xc5\x1e\xe7\x83\x2f\x00\x61\xcc\x4e\x18\xb2\x35\x17\x87\xf5\x7c\xf6\x79\x2a\x3c\xea\x8a\x01\x78\xa1\x95\xa2\x4c\x1c\xbc\x92\x11\x0c\x63\x6b\x9b\x35\x60\x1a\x35\x7f\x37\x51\xf7\x36\x91\x17\x9a\x6f\xd2\x6a\xd1\x04\xf8\x29\xb8\x17\xd2\x17\xe0\x44\x8e\x1e\x4e\x96\x2c\x59\xa8\xa1\x36\xc5\xa8\xb0\x57\x65\x62\x37\xc4\x14\x04\x07\x04\xd2\x76\x4c\xef\x15\x56\x03\xee\x55\x2e\xa5\xfd\x87\xf6\x49\xeb\xf6\x4f\xd6\xe7\x18\x83\x7f\xf0\x24\xff\xae\x39\xc0\x63\x5b\x06\x7a\x1d\x34\x68\x48\xdb\x1b\x85\x1e\xda\x65\x5e\x5e\x91\x13\x41\x0c\x26\xf7\xea\x7e\x1d\x50\x87\x8f\x11\x29\x2b\x11\x6c\xd9\x76\x0b\x44\xf3\x83\x72\xd7\x68\x74\x47\x9a\x3b\xfe\xa4\xd9\x80\x51\x47\x09\x77\x15\xfb\x55\xca\xc8\x79\xbe\xef\xa2\x8a\x37\xb1\x5a\xf6\x30\xb0\x41\x2f\x49\x12\x43\xbe\xa9\xa2\x30\xe4\xc9\x73\xb4\xf9\x0e\xee\x4b\x7e\x00\x8b\x57\xb6\x2e\xd1\x55\x81\x82\x3a\x23\x88\xc0\x82\x37\xe0\x84\x9a\x74\x49\xcf\xa2\xe1\xcd\x2d\x58\x9a\x23\x40\x63\x90\xa6\x3a\xa9\xd6\xe0\xe9\x38\x1f\x2f\x7c\x05\x4b\x52\xcc\x87\x11\xe5\xb9\xce\xab\x88\x76\x27\x4f\x0a\x67\x3b\xe7\x16\x1b\xbd\x96\xd6\x05\x8e\x9a\x8e\x1d\x6e\xa1\xdf\x31\x13\xaf\xef\x75\x53\x5f\xd1\xf8\x13\xa8\x61\x94\x85\x9a\xe2\x21\x92\xeb\x90\xb0\xb3\x04\x63\x28\xc8\x15\x6c\x61\x33\xec\xb3\x26\x27\x70\xd6\xeb\x14\xce\x21\xb5\xdf\x06\x56\x36\x0b\x6c\xcc\x47\x2d\xcf\x78\x26\xda\xa1\x78\xa4\x2e\x09\x5c\x36\x16\x50\x29\x74\x62\x2e\xf0\xab\x2b\x9a\xe1\xdb\x81\x5e\x0b\xbf\x1e\x29\x52\xe2\x6e\xdf\xee\x39\x8f\x54\xa2\xd9\xb2\x56\x80\x99\x75\xac\x67\xe3\x51\xf0\xa8\x6e\x7b\xa7\x1f\xd0\xf4\xf4\x41\x34\x25\xf3\x90\x45\x93\xb9\x37\xcd\x8e\x1e\xed\xdf\x5e\x5d\x0c\x09\xc8\x06\xaa\x92\x6a\x93\xfc\x13\x39\xd2\x6b\xfb\xa4\xb5\x5c\x87\x14\x9f\x36\x23\xf3\x46\xa2\xb0\x31\xf1\x9e\xfa\x0e\xa5\x5b\x22\x80\x5a\xd0\xf7\x7b\xcd\xe7\x5e\x76\xb2\x4e\x37\x61\x89\x63\xa7\xe4\x17\x5c\xf4\xb6\x74\xfc\x38\xa9\x49\x4e\x02\x79\xa2\x28\xb1\xb8\x6b\xbb\xde\x26\x24\x5d\xdf\xfc\x9a\xc6\xb8\x9e\xe1\x8e\xed\x20\x88\x22\x34\x22\xcf\x7e\xac\xf3\x56\xb4\x10\x19\x27\x75\x01\x4e\x60\x38\x49\x28\xeb\x27\xa7\x18\x67\xac\xd3\x29\xf7\xe6\xbe\x20\x36\xac\x59\x1f\x27\x7d\x08\x01\x47\x93\x88\x88\xd1\xa4\xb7\x09\xdc\x0d\x08\x98\xad\xd3\x0f\xad\x2a\xca\xf3\xc1\xcf\x14\x22\x8e\xa5\x88\xd9\x08\x6c\xec\xdb\xcd\x47\x52\x1e\x12\xca\x89\x5f\xea\xba\x25\x47\x23\x0d\x9a\x0c\xa8\x03\x29\x26\x9f\x84\xde\x22\x7f\x02\x3a\x81\x23\x45\x61\x99\x51\xac\xc9\xcd\xe0\x23\x54\x0b\xd5\x81\xd0\x3d\x7e\x7d\x80\x1a\x87\xb7\xb0\x8b\xc3\x2a\x3f\x91\x7c\xf0\x39\x77\xfc\x68\x47\xe7\x0f\xb5\x08\xea\x24\x03\xaa\x9b\x86\x44\x98\x85\x9b\x48\x87\x12\x2f\x31\x9c\xdc\xad\xa0\xec\xb7\x8c\x51\x4b\x9c\xf1\xd4\xc9\x80\x56\xa5\xd3\x88\x55\x8e\xbd\xab\x24\x23\x3f\x6a\xbe\xa9\x44\x0b\x9e\x72\x6d\x01\xde\x0d\x08\x83\xc3\xaf\x92\x81\x55\x0f\x78\xbd\x3e\x7a\x4a\x0c\x8f\xfb\x26\x5a\x73\xe1\xda\x83\x8a\x90\x6a\xa7\xfe\xe4\x51\x29\xf4\xb8\x77\x2a\x14\x14\x40\x92\xd9\xff\xda\x89\x50\x48\x9a\xee\xc6\xba\xb7\xaa\xce\x07\xda\xfd\x0f\x65\x43\xf3\xe7\x22\x43\xe6\xfc\x7d\x45\xb3\xff\x69\x37\x44\xdb\x53\x05\xdd\xb3\x0a\x1d\x47\xb0\x2e\x50\x73\xaf\x01\x3b\x00\x3e\xc3\x3b\x1e\x85\x0a\xc4\x43\x90\x6c\x85\xfa\xdf\x8f\xa0\x38\xef\x87\x0a\x64\x98\xc5\xd2\xe1\xf4\x4c\xec\x68\xc6\xca\x1d\x45\x6a\x25\x9a\x99\x9d\xda\xfe\x33\xc4\x21\xca\x43\x4e\x49\xc4\xac\x7c\x81\x87\xb0\x7d\xde\xae\xe5\xd5\x83\x08\x4b\xc3\x42\xb5\x91\x34\x4c\x42\x71\x05\x80\xe1\x15\x86\xaf\x3d\x5c\xb2\xf0\x2e\x26\x07\x9d\x15\x12\xd2\x8c\xf6\x83\xf3\x4f\xf4\x3b\xde\x68\xae\x0e\xcd\x0f\x99\x47\xc3\xad\x23\xa3\xd1\xf2\x07\x55\xa3\x26\x36\xce\x4d\xe1\xe3\xa9\xee\x67\xaa\xae\xc7\x16\x5d\xb1\x1d\xad\x56\xfc\x7f\xec\xbd\x79\xef\xe2\xc8\xb2\x20\xfa\x55\xd0\x48\x57\xf5\x46\x0c\x78\xdf\xde\x53\xff\xe1\x1d\xe3\x05\x2f\x78\xe3\x9f\x2b\x6f\xd8\xc6\x1b\xe0\xdd\x9f\xfe\xc9\xe6\x57\x55\x7d\x4e\x77\xcf\x39\x57\xb7\x47\xea\x91\xba\xc4\x2f\xcb\x64\x46\x46\x46\xc6\x96\x11\x81\x31\x6f\x42\xce\x9c\x74\xe1\x87\xd1\xc5\x8b\x37\x4b\xc1\x3c\x5e\xa0\x72\x4c\x85\xe7\x0e\x23\xce\x0e\x36\x08\x32\x2c\xdf\x4d\xc3\x74\xf6\x26\xad\x16\xcb\x94\x96\xbe\x04\x99\x01\x37\xc3\xb1\x0b\xbd\x9f\xae\xf9\x30\x1a\xcc\x11\xf3\xc8\x97\x9a\xb7\xeb\x34\x8d\x30\x18\x0e\xcb\xd2\x0f\x91\xbc\x54\x23\xa4\xa6\x22\x49\xab\x60\x6f\x31\x36\x67\xd5\xec\xbd\x00\x24\x91\x3d\x8d\x77\x84\x63\x39\x80\xb0\xb3\x8b\xc2\xbc\x85\x82\xeb\x93\x27\x90\x71\xb6\x65\xb1\x03\x94\xfb\x0d\xfa\x96\xee\x2f\x71\xac\x6c\x4b\x3b\x3f\xee\x7e\xc8\x44\x86\x9c\xdd\x46\x30\x60\x54\x1a\x65\x50\x52\x19\x99\x8c\xe9\x80\xe8\xa2\x91\xe0\xa9\x52\x29\xcd\xc0\xef\x5e\x0a\xb8\x65\xd1\xa3\xd7\xb1\xd2\x5c\x6e\x09\x8c\xd7\x72\x12\xf7\xa0\x6e\xc9\x4d\x8c\x45\x27\xcc\xc9\x60\x33\xa7\x33\x5f\x8e\x48\xae\x74\x20\x5b\xb7\xe6\x5e\x50\xc5\x39\x75\x4a\x35\x85\x00\x1d\x67\x58\x9c\x7b\x79\x86\x4c\x3e\xb4\x1b\xe7\xd1\x3e\x0d\xdd\x61\xc8\x41\xd0\x51\xf5\x7c\x21\xc8\x67\x67\x04\xdf\xe7\x79\x51\xd2\x16\x71\xd4\x62\xba\x3c\xc4\x2e\x9f\x00\x07\xf4\x5c\x36\xbb\x81\x91\x04\xe7\x40\xbc\x0c\x5e\x7c\xbf\xc6\xa0\x71\xa7\x20\x46\xd5\xdf\xd9\xac\x2d\xa9\x7c\xbf\x54\x53\xe0\xce\xcf\x57\xc0\x79\xa7\xed\x11\x84\x1d\xab\x90\xde\xe5\x2e\xa0\xc4\x9f\xfb\x80\xb1\xec\xaf\xf6\x95\xa2\x24\xfb\xf5\x57\xf4\x06\x10\xa4\xed\x93\x0c\x78\xf2\x1d\x9a\x6f\x31\x6f\x39\x26\xe3\x3d\x4c\xcb\x14\x5e\xaa\xe1\x30\x34\x26\x45\x98\x84\x70\xf5\xc8\x03\xe9\xb3\x56\xea\x59\x44\x94\xd4\x4b\xcb\x09\xb5\x39\x4e\xb9\x59\xa0\xe9\x16\x9c\x92\x9b\x93\xd5\xb7\x05\xd5\xe3\xa2\x67\x25\x55\x58\x29\xa9\x7b\x0b\x3d\x62\x0f\x87\xf5\xad\xa4\xe0\x2a\x05\xd3\xa6\x41\x42\xe4\x7e\xbf\x00\x75\x14\x0f\xf3\xfd\x71\x4a\xee\xf8\x0b\xe6\xca\xa1\x25\x0d\xb8\xe8\x96\x37\x84\xef\x2d\x05\x07\x1f\x59\x76\xc3\xa9\xf0\x42\x7a\x24\x5b\x2a\x2c\x31\x52\x5e\x2c\x9f\x1d\x91\xbc\xf7\x2a\xf8\x86\xdc\xf7\x59\x44\x53\xef\x91\xbe\x6c\x88\x03\x55\x31\x82\x0b\xe6\x3a\x77\xe5\x9e\x08\x28\xaf\x72\xa3\x12\x92\x18\x20\xbb\xc9\x7c\x16\x45\x2f\x2c\x38\x9f\x81\x04\x09\xaf\x3d\xe1\xa6\x10\xeb\x34\xc4\x5b\x53\x4a\x33\xb3\x33\xb4\x51\x6b\xaf\xe1\x9a\x39\x6b\x4e\xe2\xec\x56\x76\xb2\x37\xec\x90\x57\xa4\x80\x70\x49\xf6\x41\x0b\xa5\xba\xc4\x4b\x12\x15\xec\x28\x68\x20\x4e\x5f\xe9\x9a\x34\x2a\x4e\x55\x55\xb1\x54\xfb\xd1\xed\xa3\x67\xc3\x9e\xb4\x04\x7d\x30\x05\xad\x26\xf5\xc3\x1f\x4c\xfd\x3a\xe7\x18\x72\x1e\xfa\xd1\x23\xe9\x67\x59\x26\x74\xc2\x44\xa6\xf0\x3e\xe1\x6f\x4f\x9a\x94\xbc\xa2\x24\xe0\x99\x23\x06\x0d\x99\x99\x1c\xf8\x53\xfc\x28\x34\x52\x1a\x83\x92\x55\xa5\xd1\x6d\xa9\xf2\xa1\x16\x19\x38\x2e\xc5\x9e\x52\x89\x11\x22\x28\x16\x51\x6e\x9a\x37\x0d\x09\x9c\xed\x23\xe4\xd4\x53\xd0\x29\x91\x2b\x0e\xc0\x97\xd3\x45\xa9\x47\x12\xc9\x4b\x06\x02\x1c\x90\x4d\x5e\x36\x62\x90\x90\xc2\x02\x17\x14\x0a\x61\xa6\x9b\x60\x0d\x3e\x3b\x3a\xfc\xce\x4d\x32\xb9\xda\x53\x95\x83\xd7\x85\x19\xdf\xf2\x4d\x6d\x5f\x6a\xb3\x90\x6a\xcb\x65\x00\xe7\xf6\x6e\x66\x33\xb2\x6d\x2a\xf2\x64\x48\xc9\x45\x75\x9b\x67\xe7\xeb\xb5\x05\x45\x7b\x49\xbb\x31\xc5\x28\x59\x4d\x75\xb1\xda\x8a\xb9\x59\x04\xb3\x47\xdc\xcb\x72\x1b\xde\xb2\xb8\x14\x2a\x9d\x8b\x2f\x6d\x26\xd2\xbd\x52\x99\x85\x79\x4f\x0a\xa6\xa6\xb5\x19\x86\x70\x44\xbf\x79\x6f\x2b\x7c\x1b\xf8\x10\x65\x10\xe5\x2d\xe4\x5d\xe7\x4e\xb3\x82\x50\xc6\x52\x9c\x18\x39\x89\xbd\xc7\xbd\xdf\xcf\x08\x4d\x8b\x36\x42\x48\x1a\x73\xee\x9a\x3f\xf5\x01\x5d\x59\x57\x95\x7f\x2d\xa3\xab\x7e\xf5\xdc\xda\xe2\x2b\x7c\xad\x7c\x1c\xc4\x82\x7d\x96\xdd\xae\x8c\x26\x9b\x1c\xfd\xd4\xde\xae\x64\xd2\x68\xcd\x33\xf6\x2d\xae\xd8\x54\xd1\x72\x54\x95\xb1\xfb\x5e\xd0\xe2\x1e\x09\x85\x01\x3a\x43\xbc\x77\xe1\x58\x13\x3a\x9f\x2d\xf5\x3a\x3e\x5f\xb6\x8e\x6b\x39\xfb\x4c\x20\xf0\xf6\x58\x90\xec\x81\xa9\x15\x92\x5b\x73\x58\x22\xc4\xa3\xbe\xef\x23\x0c\x79\x54\x5c\xa8\x3d\x73\x2a\x09\xf7\xb8\xd0\x45\x79\x9b\x04\x14\x48\x85\xae\xb6\x68\x21\x1e\x8f\x8b\xe5\xc9\x45\x26\x75\xc0\x1b\x42\xf7\x18\x84\xbd\x98\x57\xc5\xd1\xe4\xe9\xf9\x92\x83\x34\xc3\x10\x2f\x68\x9e\x61\xf9\x94\xc2\x64\x5f\xd4\xdc\x53\xa0\x33\x3d\x08\x61\x6e\x04\xaf\xf2\x60\xca\x44\x59\x69\x17\x6e\x49\x74\x26\xbd\x95\x32\xd5\xd8\xae\xf5\xac\x1c\x2d\x7e\x4a\x36\x79\xdd\x3f\x02\xb5\x9d\xd5\x80\x43\x55\x2e\xba\x39\xc1\x5e\xcb\xce\xaa\x06\x82\x23\x58\xe3\x0e\x5c\x6b\xc8\x6c\xa4\xf1\xc9\xbd\x05\xe9\x5e\x59\x7c\xfd\xda\x54\x12\xdd\x5d\xc1\xeb\xc9\xe9\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\x16\xe7\x05\x8a\x7d\x96\xa2\x26\x7d\x12\xec\xac\xba\x0f\x2f\xe4\x01\x21\x68\xe0\x35\x64\x18\xef\xa5\x6b\xad\x0a\x97\x4b\x33\xd8\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\x79\x15\x63\xce\x9a\x01\x17\xe4\xab\x3b\xaa\x58\xb8\x49\xb6\x03\x04\x31\xd5\x7d\xb1\xc6\x42\x8f\x2a\x02\x3d\x37\x14\x9f\x83\xe2\x2d\xad\x8a\x91\x34\xd8\x4b\xd0\x90\x17\x2f\x0a\x16\x00\x1b\xac\x5b\xad\xc7\xf5\x13\xa1\x9f\x2f\x86\x51\x0a\xf7\xcc\x83\x6c\x4e\xd0\xd6\x12\x4a\x19\xab\x28\x06\xc4\x83\xf9\xa5\x60\xb8\x8c\xd2\x9e\x76\x9a\xdb\xc9\xa3\x21\x1b\xad\x3f\x8f\x73\x0d\xfa\x3a\xcd\x74\x35\x06\xd9\xbe\x20\xe4\x83\x88\xcc\x8c\xc8\x6a\xb7\xa2\xe7\xba\x08\x50\xdd\xfd\xcd\x90\x90\xcb\xdb\x7f\x32\x01\x6d\xb2\x72\x7f\x2f\x10\x06\xf3\xa4\xdc\x9d\xb3\x5c\xc1\x2e\xdc\x93\xdc\x0b\x77\xe1\x74\xda\xcb\xb9\x6c\xbd\x5c\xd9\x56\xc8\x3b\x0b\x68\x4b\x2d\x96\x3a\x53\x2d\x7b\x18\x8d\x6f\x0f\xb9\xe6\x40\xf6\xcc\x45\x6a\x33\xbb\xa0\xf5\xf2\x7a\xb5\x3b\x31\xc2\x48\xbc\x33\x89\xe6\x20\xfe\xad\xd9\x5a\x70\x9f\x64\x46\x4b\x86\xe0\x39\xf6\x38\xa6\x3d\x79\x03\x15\x5e\x9e\x44\xef\x4d\x35\xc6\x9d\x91\xd1\x91\x48\xb7\x78\x33\xc4\x53\x45\x12\xa4\x17\x0e\xed\xed\x97\xe8\x06\x42\x1c\xbd\x9d\x0e\x28\x2b\xba\x77\x1f\x74\x0e\x07\xb9\x2a\x8c\xd5\xc5\xef\xa5\x33\xa0\xe1\x2a\x4c\x0e\xa3\xa4\xd2\x6a\xa3\x71\x73\x8a\xbe\x23\x9b\xfa\x33\x9d\x42\x1e\xfd\xc5\x3e\x66\xcb\xcc\x5f\xf9\x04\xe1\xc7\x77\x7b\xe3\x77\x40\x84\x8a\xf6\xcc\x61\x7a\x32\x04\x39\x28\x8b\xf3\xbb\xc9\x24\x36\xf7\x0b\x4f\x0f\x52\xef\x3d\x11\x24\x77\x47\x65\x94\x14\x39\x66\xa9\x8c\x44\x57\xd4\xcc\xbe\x70\xda\x64\x60\x51\xce\x17\x67\xe7\xc5\x75\x67\xb1\x52\xdd\x37\x4b\x5f\xcd\x30\x86\x93\xa8\xb1\xb0\x1e\x09\x9a\xa1\x4a\x96\x76\xe8\xa9\xed\x96\x64\x3d\x97\xcb\x4c\x42\x3d\x85\x88\xe0\x37\xe6\x2b\x24\xa4\x48\xbc\xc2\xa7\x99\x42\x23\x3d\xd0\xc7\x53\x75\xaa\xf5\xea\x2e\xba\x80\xdb\x0f\x7b\xe5\x39\x8e\x71\x9d\x98\x3e\x33\x11\x7a\xe2\xca\xe0\x78\xf1\xfd\x2c\xf2\xa6\x39\x2a\x44\x07\xba\xc7\x61\x1d\xf6\x6a\xeb\x45\x45\xf9\xd2\xcd\xb3\x31\x09\xaa\xbc\xa0\xe6\xc4\xb1\x9d\x73\x41\x5b\x64\x2a\xcd\x87\xdb\x30\xa0\xe0\x3f\x4a\x43\xe7\x79\x26\x4f\xd8\x6c\x94\x59\x53\x54\x27\xac\x57\xba\x40\x6e\x21\x1d\x4b\x72\x52\x92\x4b\x31\x00\xfc\xc2\x53\x3d\xbf\x2b\xaf\x3c\x57\xb6\xf5\x08\x54\xaa\x97\x31\xe7\xe8\x35\x59\x32\x3e\x94\xd1\x33\x40\x75\xfe\xc9\x36\x8d\x3d\x4b\xaf\x16\x53\xf1\x4c\x84\x1a\x98\xb5\xc7\x17\x0d\x52\x50\x24\x44\xbe\x72\x07\xda\xc7\x12\x79\x04\xc6\xe7\x86\xd4\x3c\x24\x8a\x20\x28\xf6\xea\x9b\xe8\x63\xbc\x32\xf7\xfd\x9b\x10\xe9\x31\x03\xe9\x89\xcd\x15\xfc\xac\x5e\x01\x10\x1d\x0c\x82\xea\xc9\x40\x82\x2f\x00\x71\x5e\x52\x9c\x6a\x70\xb1\x21\x93\x71\x8e\xec\x20\xeb\x98\x27\xcd\x65\x27\x59\xa9\x65\x20\x71\xc2\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\x9e\xc9\x77\xdc\x8f\xba\x05\x8c\x31\x90\x64\x55\x8e\x14\xe3\x0b\x5d\xae\xa7\xdc\xb5\x53\xef\xb9\xe7\x7b\x85\x14\x06\x6d\x10\x4a\xcc\xac\xd1\x89\xb6\x48\x3c\x9f\x25\xb8\xf0\x91\x1a\x54\x07\x94\x64\xe6\xf7\xc5\xa8\x82\x3a\x8a\x73\x52\x02\xe5\xe8\x81\xd8\x58\xde\xd3\x30\x35\xd1\x49\x29\xb3\xf6\xe9\xcd\x4b\xc1\xbc\x94\x5d\x90\x8a\x30\x8f\x4a\x63\x21\x04\x46\x6a\xb1\x78\xe9\x4b\x20\x95\x6b\x60\x4c\x4a\x1d\xd6\x6b\x0e\x56\x8b\x58\x9b\x9e\x63\xd9\x67\x41\x91\x74\x9b\xeb\xe5\x36\x30\x92\x25\x68\x3c\x33\xd5\x6d\xbf\x70\x88\xe8\xa1\xc3\x9d\x6b\xdb\x65\x79\xd1\x3d\xf8\x28\xce\x06\x97\xc4\xac\x18\x32\x38\xed\xa6\x18\xfa\xf4\x43\xbd\xd9\x6b\xa2\xa3\xc7\xd7\x94\xe6\xe9\x97\xf1\x22\x40\x7d\xee\x24\xe5\xcf\xfd\x2e\x7e\xde\x36\x7f\x2d\x7b\x7d\xfc\xfc\x58\xbc\x68\xbb\xb7\x0d\xf2\xf6\xf4\x06\x0a\xec\x15\x9e\x97\x58\xf7\x9f\x62\xf1\x6c\xed\x73\x43\xc3\x2f\xa8\x51\x1e\xd7\x38\x17\x73\x89\xc5\xa2\xde\x3b\x95\xd3\x40\x31\xfc\xe5\x6d\x75\xd7\x81\xa9\x8d\xc1\x7c\x5b\xb4\xd4\x26\x0f\xf6\x5d\xbe\x9e\xad\x6d\xbe\xe0\x8c\x3d\x6b\xc6\xfe\xaa\x29\x15\xd6\x47\xc0\x84\xa8\xd5\x72\xce\x10\xb4\xe2\xb4\x7a\x18\x6a\x6d\xb9\xf0\xa8\x28\x5e\xc6\x89\xdc\x77\x94\x67\x14\xf7\x1a\x74\x78\xd0\xc7\x00\xe2\xb6\x2f\x4e\xd5\x3e\x1e\x2e\x59\x17\x23\x3a\x15\x01\xd3\xa8\xdd\x32\xa2\x76\x03\xd5\xef\x34\xbb\xf2\x00\x21\xea\x80\xa1\xd4\x08\x80\x3c\x63\x81\x69\xa6\xf3\x52\x91\xd3\xf2\x34\xb9\x87\xc8\xc3\x81\x73\x42\x9d\xeb\x2b\xae\x1b\xdb\x4f\x01\xaf\xe0\xb3\x6a\xde\xb3\x13\xc2\x65\x34\xd6\xa9\x4b\x2c\x34\xe5\x90\x62\xea\x84\x08\x13\x65\x55\x27\xf0\x2c\xa5\x04\x75\x6b\x90\x07\x2a\xd2\x9c\x2a\x35\xc5\xf9\x2a\x77\x8f\xf0\x4e\xcb\x9e\x8d\xfa\x00\xac\x0d\xd6\x7d\x3e\x11\xd8\x55\xb8\x4c\x01\xc5\x56\x6f\xd0\xab\x4b\x7d\x55\xea\xe4\x62\xe0\xa3\xa6\x72\x6d\x23\x78\x38\xcd\x97\x2f\xa3\xd4\x1c\x48\x6e\x2f\xbd\x36\x5a\x00\x2d\x0a\x0f\xde\x96\xb8\xac\xaa\xb1\x3d\xc0\xa9\x2a\x84\x03\x54\x9e\x32\xcd\x48\x2f\x82\x2c\xb5\xa3\x7e\x7e\xe3\xea\xa3\x9c\x04\x1d\x69\x1d\x10\x4d\x03\x9d\x30\x17\x55\x4f\xf0\x69\x70\x55\x28\xd5\x6c\x46\x85\x6d\xd9\x2f\x99\xa0\x47\x8c\x34\x13\x9f\x59\x0a\x53\x67\x24\xe5\x4a\x45\xc9\x4b\x57\x8b\x39\x24\x2d\x06\x49\xe2\xcc\x8c\xa3\x66\x31\x81\x2b\xd6\x01\x1d\xf4\x24\x78\x3d\x3b\x5d\x31\xae\x1c\x48\x6e\x41\x5a\xa9\xa0\x5b\x10\x11\x82\x92\x9b\x18\xd5\xb0\x3a\x8a\x31\x19\x35\xd3\xea\xa8\xbf\x10\xf1\x6c\xc3\x64\x44\x75\xf5\x9d\x64\x01\x03\xbc\x75\x26\x2a\x4a\x55\x62\x58\x0f\x92\xd6\x15\xf3\x44\x10\x30\xe3\x46\x69\x2e\x5c\xb8\xfb\x9d\x1d\x80\x8e\x3c\x51\xdd\x05\x1c\x10\xf3\xe1\x10\xce\xab\x48\x12\x4f\x29\x17\xee\x3e\xf8\x8f\x07\x49\xf6\x5e\x56\xa2\xe7\x51\x6a\xdf\xfe\x54\x29\x3e\xa0\x42\xa9\x1f\x95\xd2\x20\xf2\xd4\xe3\x76\xd7\xf4\xb7\xc5\x72\x08\x60\xa4\xca\x9c\xb8\x57\x9a\x73\xf0\xd1\xa5\xe8\xf7\x2c\x45\x6c\xc1\x80\x3d\x44\xbf\x80\x86\xd5\xfb\xaa\xec\xef\x8d\x40\xc0\x83\x94\x25\x81\xc2\xbd\xd1\x91\x55\xa4\xcb\xeb\xed\xd7\xb6\x42\x43\xa8\x6e\x35\xaf\xa7\x75\xe6\x69\x3b\x2f\x6f\x6f\x8e\x20\xac\x01\x51\xe4\x7d\x24\x81\x7b\x26\x21\x23\x3a\x0c\x2b\xfa\xf2\x6e\x42\x30\x48\x3b\x0e\xa5\x20\xc5\xbf\x17\xcd\x6b\xa8\xe7\x9b\xd2\xba\x66\x41\x03\x69\x31\xd2\x8c\x82\x5a\x88\x42\x90\x9e\x3f\xff\x99\xe7\xf1\x23\x18\x82\xbf\x98\x81\x7f\x7f\x78\xcd\x93\xb4\xc1\x4f\x66\x5c\x6b\xf9\x85\x9f\x93\xa7\x31\x67\x46\x13\x9a\x8c\x55\x3a\x52\x63\xb2\x0c\xaf\x5f\xe9\x87\xd1\x5a\x7c\x9d\xf0\x7b\xba\x26\x05\x75\x35\x74\x45\x6b\x8c\xb8\x97\x68\x1e\x79\x35\x4f\x59\x3b\xd3\x92\xf4\x7c\xd2\xf0\xe3\x7d\x31\x29\x24\x08\x70\x40\x23\xe7\x5b\x6f\x4f\xf3\x54\xbc\xbd\x37\x72\xbf\x57\x4b\xb4\x84\x57\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\xb6\xab\x64\xa6\xee\x3a\x93\x2c\x7c\xea\x3a\x42\xef\x2b\xf1\x3c\x94\xba\x18\xa8\x3e\x7a\x2f\xa1\xc0\xb4\xf6\xd4\xf3\xa5\x63\x7c\x49\x17\x55\x54\x17\xb5\x39\xf6\x97\xbd\x36\x77\x58\x0f\xf0\x57\xff\x3e\x3f\x28\xf7\xfd\xbc\xd5\xd5\x73\xaa\x61\xe0\x52\x40\xd6\x58\x03\xe2\xd0\xd5\x27\xac\x40\xaf\x4a\x9f\xa0\x85\x76\x9f\x1a\xa1\x79\xbe\x4d\x63\x80\xae\xcb\x25\x24\x23\x5a\xea\x91\xfd\x8d\x23\x1a\x0e\x38\x55\x84\xd7\x4f\xcb\xcb\xb4\x35\xae\x8b\x8b\x5e\xc9\xaf\x95\x8b\x75\xc2\x14\x25\x8c\x57\xd6\x5e\x6a\x5c\xe9\x8b\x69\xa9\x1d\xdc\x88\xc9\x62\x9f\xcf\xe7\xb7\x4c\xc5\x82\x1b\xf3\x27\x42\x2a\xd0\x98\x81\x29\x25\xe7\xad\xc4\xe6\xcf\x5e\x4c\x00\x31\x7d\x45\x94\x3d\x94\x0f\x25\x7b\x7a\x93\x1a\xbf\xf4\x9d\x77\x65\x86\xf0\xac\xeb\x56\x7c\x01\xe8\x13\x36\xce\x2d\x9b\x8d\x2a\x00\x9d\x16\x56\x2c\x2b\x7a\xb9\xbc\xe5\xa9\x87\x13\xb6\x8f\xf1\x1b\x7c\x2e\x12\x58\x1d\xaf\xd9\xd3\xf6\x14\x5c\xab\xe1\x1b\xed\x08\xd7\x52\x1b\x09\x30\x94\xc1\xdc\xac\x45\xfa\x45\xbd\xc6\x53\x77\xa9\xae\xe6\xb3\x9d\x20\xad\x3d\xcd\xb2\xe9\xd4\x9a\x5e\x37\x6a\x23\x53\x45\x04\x33\x8f\x90\x43\x87\x02\x3b\x8b\x0e\xa6\x15\x4c\xc3\xeb\x2a\x2a\x08\x35\xdb\x25\x67\xc1\xbd\x58\x68\xdd\x9d\xf8\xfb\x33\x33\x66\x39\x10\xae\xae\xa0\x8c\x04\x88\xd2\x67\x18\xbf\x09\x13\x70\xe3\xf9\x1c\xf1\x67\x1f\xbc\x40\x5c\xf5\x46\x79\xf9\x6a\x9f\x68\x32\xb3\x6b\x0b\x6f\x73\x09\xe4\xf8\x93\xe2\x37\xe9\x3e\x84\x49\x93\x35\x7b\xcd\x33\x81\xdc\xb0\x9f\xba\xcd\x1b\x7b\xcd\xc9\x3a\x5c\x69\xe2\xfa\x31\xed\x45\xcf\x4f\x39\x4b\x30\xeb\x17\x45\xf0\x31\xfc\xf4\xac\xd2\xcb\x6c\x2b\x11\xb3\xc9\x8f\xb0\x56\x2e\x35\x4f\xc5\x38\x51\x31\xe1\xab\x3a\xde\x6f\x8e\x4e\x4b\xf9\xbe\xe9\x44\xcd\x9d\xa1\x3b\x7f\xb3\xe5\xa4\x41\x5f\x11\x3a\xb7\xd2\x5e\x20\x9d\xa2\x55\xa4\xf3\xdd\x8f\x38\xca\xf0\x53\x06\xe0\x34\x5d\x7d\x76\x2e\x53\xb6\x35\x23\x59\x24\x3e\x55\x9c\x7a\x65\x1a\x40\x77\x63\x50\x61\x70\xe7\x76\x8f\xf9\xf0\x7c\xfd\x3c\x2f\x97\xc6\x4e\xd2\x52\x0e\x54\xdc\xfd\xa9\xf7\xae\x3c\x9e\x49\xfa\xbf\xbe\x5f\xfe\xc5\x6e\xbd\xff\x79\x9b\x5b\x6b\x93\x65\xbf\x3d\xc5\xae\x45\xe3\x4a\x7d\x16\xee\x64\x36\x4f\xf1\xac\x69\x61\x3e\x66\x05\xd4\x49\x5d\x28\x76\xde\xe9\x0d\x66\xd1\x58\x0d\xe9\x25\x76\xcb\x18\x67\x7a\x34\x6a\xbc\xbe\xea\x4c\x9e\x47\x6e\x72\x4f\x0a\xe9\xa5\x64\xa1\x42\x6a\xbc\x8e\x45\x1e\xfa\x3d\x8e\x00\x52\xb7\xa5\xe7\x52\x30\x2a\x31\xde\xf7\x77\x20\x6b\xbb\x16\x46\xfd\x68\xe9\x93\xb7\x68\x47\x60\xd5\x30\xa5\x7f\xa5\x7d\x7a\x9f\x93\x6d\x18\x7b\x1d\xbd\x3c\xa4\xab\xd9\xbd\x10\xaa\x78\x13\x48\x0b\x88\x6f\x8a\xbb\xda\xbe\x7e\x49\x82\x6a\x1c\xfc\xfa\x14\xbf\x63\x13\xb4\x6a\x2e\x09\x7b\x36\x6c\xc7\xb3\xf8\x7a\x7a\x7b\xfb\x4e\xc1\xa7\x57\x45\x64\x8b\x40\x8b\x00\x7a\x4d\xb5\x37\xd4\xb3\x23\x7f\x06\xbb\x77\xc4\xb0\xa4\x0d\xca\x21\x04\xe8\x46\x71\xea\xa8\xf3\x64\x29\xb5\x82\x5f\x99\xbd\x0f\x2f\xb4\xa4\x5e\xce\x8c\xa8\x78\x55\xd7\x86\x3c\xed\x33\xed\x44\x9e\xea\x17\x2b\xca\x8e\x15\xd1\x1e\xd9\x9f\xee\x18\xff\x7c\x55\xa2\x37\x40\xa4\x73\xc1\x1d\x8e\x4f\x40\xdd\x6b\x65\x9a\xd1\xc8\x3d\x4d\xa7\x79\x10\x56\xbe\xa0\x69\xe7\x2b\x67\xc0\xa6\x2d\x44\xe4\xfe\x46\x89\xe0\x45\x37\x51\x5d\xf6\xc7\x41\x0e\xde\x39\xa8\xd2\x69\xee\x03\x17\x43\x64\xe9\xe0\x91\xa9\x9a\x89\xd6\xdc\x4d\x0d\xa4\xfa\x2d\x33\x62\x49\x80\x96\xae\x5a\x51\x54\x40\x9a\x21\x22\x1e\xc0\xd2\xae\xc2\x23\x40\x4c\xbb\x0e\x96\x99\xa6\x23\x9d\xa7\x8b\xab\x15\xed\x5b\x87\xa8\x56\x48\xd5\xd7\x8b\x4e\x42\x5b\xf4\x4f\xaa\x84\x77\xc9\x0b\xa4\xa9\xe6\xea\xd0\xd9\xab\x87\xdb\x7b\xe8\xfb\x8f\x56\x21\x4a\xf6\x86\xe0\x24\x92\xd2\x04\x78\x45\xae\x32\x01\x30\x28\xa3\x35\x17\x10\x06\xc5\x91\xa1\xae\xcf\xf1\x4e\x2f\xa4\x92\xaa\x9d\x5b\x03\x5a\xe1\x90\xfc\x29\x6d\x18\x12\x8a\x88\xda\x1f\xd9\x99\xb9\x95\xbc\x53\x9c\xa2\x97\x7a\x95\x85\xba\xa8\x92\xec\x7c\xbd\xe8\x03\x7f\x67\x6b\x39\x07\xef\xf4\x4c\x73\x67\xf9\xee\xb1\x40\x46\x22\xd7\xe0\x76\x3d\x3f\x82\x00\x2b\x69\x4d\x79\x5e\x84\x17\xed\x75\x25\x4f\x37\x6f\x7a\xbc\x50\x3d\xd6\xce\x57\xcc\x9e\x94\xbb\x0d\x26\x48\x03\x09\x6a\x0f\x4d\x68\x4f\x5c\x38\xff\x05\xc2\x8c\x4c\xab\xb4\x63\xbd\x2d\x4d\x79\xcb\x90\x9a\x29\xfa\x83\xac\x34\x01\x1c\x84\x6a\xcf\x42\xb7\x61\x94\x99\xd1\xf3\x78\x94\x16\x6b\xc8\xa5\x69\x2b\x58\x78\x6b\xb4\x5d\x84\x59\x6c\x4b\x4d\xce\x70\x03\xd1\x2f\xb4\xd5\xfb\xf7\x60\xf8\x96\xa9\x8c\x65\x66\x9a\x78\x65\x05\xfe\x9c\x83\x6e\xf9\xa4\xcf\x6f\xc1\x9c\x90\xa6\xcf\x30\xa0\x54\x3b\xac\x1c\x48\x46\x19\xbd\x27\xa8\xa2\xa5\xf5\xf4\x15\x88\x48\xe0\x5e\xc6\x46\x1d\x2f\x1f\x40\x04\xdf\xf4\x1a\x36\xa5\xbd\x7f\x25\xef\xdc\xf0\x6a\xe6\x24\x75\x94\xf9\x2e\x62\x05\x23\x07\x86\x71\xb9\x0f\x02\xfc\x54\xa2\x7d\x7e\xa7\x69\x26\x37\x4e\x88\xce\x47\x50\x0e\xfc\xa9\xae\xe2\x2f\x96\x9e\xcf\xe7\xa7\x23\x64\xa0\xcb\x43\xea\xa5\xd2\x86\xd0\xc2\xb2\x0f\x3c\x86\x86\x1e\xfd\xf9\xc7\x8d\x40\x72\x62\x32\x1f\xee\xca\x98\x65\xf2\x9b\x1b\x3f\xc3\x07\x98\x13\x44\x0f\x48\x39\xf3\xbc\x71\x60\xee\x2c\x8e\xa6\xf2\xd0\x68\xc0\x4e\x13\xd8\x19\x1e\x55\xce\x35\x29\x30\xdb\x47\x9e\x6f\x7f\x29\x0b\xe9\x41\xee\x25\x6e\x42\x2f\x75\xd6\x45\x22\x54\xc6\x22\x9f\x26\x22\xd4\x86\xb5\x8a\x27\x1c\x98\xfb\xae\x39\xf8\x95\x8d\xaf\xef\x43\xd7\x01\x7d\x8b\xcc\xa5\x53\x8a\x27\x22\x34\xc6\x62\x4b\x49\x85\x50\x84\xf0\xb9\x94\x84\x4c\xb3\x59\x86\x0b\x91\x73\x29\x71\x76\xaf\xce\xd0\x43\xe5\xf8\x49\xe2\x7c\x58\x79\xf0\xa0\x76\xf5\x61\xd5\x1a\x53\xf5\x41\x4f\x6a\x4e\x8e\xeb\x9f\x96\x83\x93\xc6\x35\x90\xf6\x68\x66\x6d\xa6\x53\x89\xfd\xfa\x7b\xa0\xa9\x7e\x3a\x17\xb7\xc7\xd3\x32\x79\xff\x07\x3d\x51\x65\x56\xba\x75\x6e\xe2\x93\x39\x5e\x72\x72\x88\x91\x18\x51\xea\x68\x51\x2a\x6a\xbe\xcd\xe4\x74\xb9\x16\x98\xb2\xd0\xb3\xb2\x48\xb3\xe2\x9d\x8b\x5b\x0e\x2d\x89\x8b\x81\xbe\x97\x76\x61\xad\x3e\x7e\x85\x97\xbf\x79\xda\x23\xaa\xca\x31\x16\xcb\x21\xcc\x99\xf9\x26\xfa\xb8\xef\x9e\x87\xd8\x33\x28\x29\x97\x7e\xf2\x40\x84\xc6\x5f\xaf\x19\xd6\x6a\xff\xc5\x93\xde\x87\xa9\x4e\x41\xb2\x2c\x62\xc9\x49\x79\xd0\x83\x94\x33\x68\xe8\x4e\x7d\xb4\x3c\xd1\xd0\x63\xb4\xeb\x15\xcc\x83\x93\x09\x46\x5c\x33\x28\x30\xb6\x28\xd5\x87\x57\xca\x26\x4f\x0a\xf5\x3d\x7a\x50\x2d\x74\x54\x60\xa8\x53\xe6\x9f\x6b\x46\x88\x69\xdd\x5c\x9f\x92\xaa\x0c\x8c\x4f\x34\xae\xcc\x54\x1f\xcd\x3f\xe4\xff\x08\x61\x70\x48\x44\x61\x54\x16\xbe\x57\x59\x6a\x71\x4e\xe5\x78\xb3\x28\xeb\xe6\x69\x43\xec\x9d\x1f\xab\x2e\xdd\x72\x35\x97\x4e\x59\x17\x71\x4f\x2e\xaa\x9c\x2c\x16\xa9\xd9\x11\xa9\x21\xe4\xc0\xdc\xf8\xd0\x9f\xda\x62\x36\xc4\x22\xb5\x04\x22\x35\x4a\xbc\x76\xd5\x72\xba\x71\xe0\xb2\xbf\x89\x14\x12\xcd\xc5\x67\x3e\x0f\x69\x97\xa2\xec\x23\xc4\xcc\xc2\x4a\x2b\x2d\xdb\xa0\xa4\x55\x57\x58\xec\x19\xb8\x06\x6e\xda\x06\x76\xe1\x7c\xcc\x00\x35\x51\xbd\xf2\xa8\x7a\x15\x04\xf5\x5a\x72\xe6\xa3\xe4\x34\xd0\x61\x8c\xab\x8f\x18\xd7\x02\x54\xaf\xfc\xaf\xf0\x99\x83\x8f\x38\xdd\xcd\xc5\xc0\x5f\xe1\x2b\xfe\x11\x9f\xf9\x2f\xf1\xe9\x39\x4d\xae\xf2\xb9\xda\x20\x6e\x8a\xce\x1c\x78\xb7\xf2\xc6\xdf\xe6\x10\x06\xd3\x2f\x1e\xe2\x81\x8b\x2d\xb1\x28\xf4\x3e\xec\x9c\x4d\x0e\xcc\x57\x78\xa5\x2a\x9f\x37\xee\x29\x98\x5c\x81\x6a\x8f\x92\x33\x6c\x7f\x52\xaf\xe9\xa4\xda\xf6\x74\xb1\x35\xf1\x62\xab\x88\x69\x0b\x8c\xf6\x88\x99\xcb\xd5\x98\x54\x4b\xfa\x81\xef\x26\x52\x8f\xd8\x85\xca\xb0\x36\x7f\x85\xcf\xfc\x47\x7c\xc5\xbf\xc4\x37\xac\xb4\x2b\xc8\xef\xe8\xe2\xaa\xa3\x2c\xb5\xe9\xa3\x5d\x98\xe2\x07\xee\x63\x6f\x9b\xfd\x5d\xd1\x54\xe7\x28\x34\x12\x85\x47\x00\x3b\xa0\x24\x3a\xfd\x6a\xe7\x51\x2e\x01\x7a\x73\x25\x17\x83\xa4\x69\xfa\x1c\x5b\xb6\xc9\x38\xa7\x47\x10\x0b\x5a\x78\x9d\x34\x93\xd7\x31\xb8\x23\x2c\x30\x2c\xba\x50\x16\xe8\xe1\x6a\x3b\xc1\x88\x83\xfe\xab\xe0\x27\xfb\xca\xe1\x0d\x47\xa0\x2f\x16\x98\x39\x60\x7c\x02\x69\x46\x92\x98\xc7\xf3\x12\x68\xd2\xb3\x6f\xd8\xb9\xfa\x94\x18\x51\x2d\x7c\x13\x6f\x60\x24\x08\xf3\x3d\x81\x24\x70\x1f\x81\xe8\x00\x29\xe6\x45\xed\xea\x9b\x7e\xd5\xef\xf7\x41\xd7\x4e\xaa\x38\x2b\x1c\x43\xb4\xe1\x19\x8e\x72\xdb\x2a\x73\xc4\x46\xb0\xb6\x2a\x64\xaa\x23\x26\x6a\x20\x6a\x38\xe6\x80\x94\x94\xed\xc2\x1e\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\xec\x65\x86\xeb\x33\x5f\x90\xba\xdb\x8a\x67\xc7\xb9\xf6\x99\x1b\x3e\xd3\xea\x34\xa2\x84\xc0\x10\x31\x45\xba\x29\x5a\x39\xae\x8c\xc1\x0d\xd4\x4e\x97\x14\x71\x02\x44\xaf\x84\xe7\xde\x80\xf5\xd8\x7e\xf5\x81\x60\xab\x14\x30\x8c\xfb\x0b\x1e\xe9\x48\x38\x8d\x15\x8a\x7b\x63\x06\xd1\x8a\x89\x00\x83\x02\x25\xfb\x4c\x7c\x44\x11\x55\x34\x56\x64\xb7\x57\xeb\x85\x44\x8d\xc3\x19\xad\x77\x46\xc6\xa5\xc1\x4e\x7c\x8b\x44\x65\x7a\xd3\xd4\xab\x13\x4f\xd0\x15\xe4\x9f\x44\x54\xe3\x00\x60\x98\xc6\xa8\x66\x0b\x8d\xf7\xb7\x93\xc2\x61\x91\x24\xf0\x82\x25\x4b\xf6\x5e\x24\x15\x79\xdf\x85\xa0\xdc\x8a\x37\x39\xba\x9e\x1b\x7e\xd6\x41\x92\x0e\x9f\x91\x32\xe3\x6d\xa8\xcb\xb1\xf1\xce\xd3\x98\x16\x03\x6e\x74\xa7\x96\x3b\x41\xbd\x18\x96\x39\xeb\x4b\x69\xa4\x92\xae\xa0\xa7\xa4\xfa\xc2\xf4\xc7\x12\xcf\x3d\xfa\xf0\x43\x96\x47\x51\x3e\x79\x7a\xea\xa9\x1f\xbd\x64\x4f\x93\x13\x22\xcb\xfe\xe4\xb7\x8f\x21\xb4\x97\xaa\xd4\xc5\x27\x53\xf9\x71\x2a\x41\x8d\xff\xb0\xd4\x50\x41\xe9\x06\xf2\x3d\xb5\x88\x54\x98\x8b\xe1\xa9\x0e\xe9\xa0\xd2\x0d\xfa\x95\x42\xe2\xc5\x54\x6e\xf1\x1c\x55\xfe\x35\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\xbd\x5a\x0c\x46\xa2\x00\x02\x5c\xc5\x24\xe5\x2f\x79\xb7\xe7\xcc\x68\x30\xd0\xcb\xed\x9c\x43\x4a\x3a\x4a\x86\xec\xb0\x29\x9c\xe3\x75\x08\x49\xc4\x09\x61\xde\x88\xe1\xbe\xae\xd4\x93\xa1\x75\xaa\xe7\x7c\x6c\x7a\xc4\x96\x8a\x98\xaf\x29\x69\xec\xe2\xee\xd4\xfc\xc5\x25\xed\x42\x99\x0b\xde\xbc\x6a\xde\xa3\x50\x89\x0c\x91\x46\x5c\xd3\x86\xd3\x88\x9f\x1f\x7d\x46\x67\xce\x3b\x0c\xc0\xbd\x91\xd0\x4a\xb3\x44\x12\x55\x1b\x26\xe8\x0c\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\x71\x85\x72\xcc\x56\x5e\x67\xad\x0b\x9e\x0a\xc9\x72\x34\xdb\x16\x93\x2e\xdc\xcc\x49\x19\xff\xe4\x6f\xd5\x14\xc9\xfc\xd7\x8a\x27\xca\xdb\xcf\x74\x03\xfa\x7e\x97\xab\x4a\xf4\x00\x4c\x77\x67\xdb\xb5\xf1\x57\x9e\x5b\xbe\xdf\x60\x7c\x55\xe9\x1c\xcb\x51\xf4\x09\xc5\xdb\x89\x8c\xf8\xfa\x11\x00\x7b\x96\xa1\x48\x6a\xd9\xfb\x7b\x55\xd6\x53\x35\xe7\x5a\xdf\xa0\xd9\x28\x0c\x5c\x86\x69\x52\x9f\xa3\xe0\x0e\xbe\xf5\x31\x71\x2b\x8d\x5b\x1b\x2e\xf2\x0d\x09\x4b\x64\x79\x20\x35\x22\x8d\xa9\xd4\x3d\xfc\x84\xbb\x20\x6a\xe9\x56\x09\x18\x3e\xec\x2e\x23\x13\x12\xb8\x5f\xe0\xee\xb4\x4c\x88\xf7\xb2\xf9\x02\x03\xfb\x7b\xb7\xd7\xe2\x3a\x8b\xab\x08\xb1\xca\xbb\xa6\x17\xce\xed\x4a\xb2\x33\x0e\x82\x5c\x23\x49\xd6\xe0\xdc\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\x6c\xcb\xc4\x7b\xc2\x2f\xcb\xb0\xbc\x94\x67\xdb\x0c\x74\x16\xd0\x13\x8d\x70\x36\x63\xd4\xf0\xd5\x16\xda\x92\x90\xc7\xeb\xbd\x42\x6f\x14\xd7\x5c\x30\xc5\x25\x7a\xdd\xcb\x29\x77\x7a\xde\x6b\xe2\x26\x0b\x20\x35\xcc\xfa\xe4\xc1\xb9\x1b\x69\x66\x21\x8b\xb7\x05\xac\x0c\x57\x6e\xb4\x96\xa4\x1d\x06\x9f\xa0\xd9\xf4\xe1\xa7\x5f\x47\xb0\xa2\x34\xf7\xde\xbb\x4e\x6a\x4a\x97\x55\xe9\x49\xf7\x3a\x65\x27\x6d\xe2\x17\x75\xcf\xe9\x03\xae\x19\x01\xcc\xcc\xa9\x92\xde\x66\x0f\x3f\x5f\x49\xa4\x4e\x4f\x57\x0d\x13\x69\x05\x74\xad\xc6\x36\x0a\xcb\xa8\xbd\x62\x66\x32\xa0\x00\xc5\x24\xbd\xd2\x41\x19\xab\x30\xd8\x5e\xe5\x21\xe9\xf6\xf3\x9c\x49\x37\xfa\xc9\xb3\x41\xa5\x80\x0f\xdb\x4a\x90\x46\x60\xb3\x09\xb9\x36\x4f\x15\xbd\x26\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\x05\xa7\x7f\x5a\xec\x95\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\x6c\x2e\xa0\x09\x13\xa2\x4f\x30\xc2\x59\x89\x45\xa3\xd9\x80\x99\x22\xe0\xd0\xd9\xd4\x54\xba\xaf\x93\xed\x48\xd1\xe8\x35\x60\xa9\xfc\x54\x3c\x6c\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\x62\xdf\x2e\x8f\x94\x1f\xeb\x7e\xe9\x88\x97\xb2\xe0\x57\x24\x9a\xad\xca\xd0\x51\xa4\x5f\x1e\x89\x94\x5f\xcf\x2a\x9e\x37\xb8\x0b\x51\x0c\xa0\x29\xac\xac\x3a\x22\xbb\x14\x6c\xa3\x98\x00\x58\xbe\xef\x17\x09\xbe\x6b\x33\x90\xf5\x32\x0b\x09\xd7\x56\x06\xde\xa1\xa8\x25\xaa\xc9\x92\xf1\xe9\x79\x62\xe6\x7b\xbf\x1f\x68\x5a\xa5\x15\x00\x7c\x0c\xb4\x73\x33\xca\x3f\xf7\x63\x84\x32\xf9\xab\x3d\x4f\xf4\xef\xc4\xe2\xef\xc4\xe2\xff\x86\xc4\xe2\x71\xe3\xd7\x3f\xed\x7a\xfe\x99\x08\xd8\xd2\x78\xe1\x1d\xde\x7c\x18\x98\x7a\xbd\xf1\x6a\xe1\x30\x26\x6f\xff\x7b\x89\xc5\x0f\x7c\xda\xbf\xc4\xf7\xdf\x4c\x2c\x44\xad\x30\x45\xad\x30\x20\x95\xff\x99\x08\x18\x0f\x1a\x35\x6d\x53\xd4\xb8\x62\xd2\x0a\x63\x36\x6d\x81\x37\xff\xbd\xc4\xe2\x27\x3e\xfb\x5f\xe2\xfb\x3f\x93\x58\x94\xd0\x48\x11\xd2\x9a\x58\x64\xdf\x13\x8b\xec\xac\x29\xe1\x74\x36\x05\xf5\x0e\x8c\x3a\x2d\xa9\xd2\xa4\x16\xb6\x44\x74\x16\xe8\xf8\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\xc4\x55\xe3\x70\x4b\x6c\x20\xc7\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\xb4\x1d\xdf\xa9\x82\x7d\x3b\x44\xcd\x30\x91\xb3\x5a\x0b\xb7\x13\xad\x9e\xf5\x33\x73\xbe\x73\xcb\x0b\x1b\x9e\x1e\xbe\x07\x06\x0e\x7b\x35\xc0\x42\x70\x17\x95\x89\x1b\x20\x86\xf1\x0e\x7f\x08\xea\x19\xc9\x7d\x0c\x7a\x30\x0b\xaa\xee\x15\x1d\x1f\x27\x7e\x44\x41\x71\x86\x91\x97\xbf\x30\xc8\xe9\x42\xdc\x9f\xd5\xf3\xc6\x5e\xaa\x3b\x7f\x0f\x08\x2f\x44\xb5\xe9\xf2\x66\xd1\x72\x08\xf5\x6b\x93\xc0\xb3\xcc\x23\x32\xa4\xc7\xfa\xa8\x5d\xba\x53\x3c\x11\x14\x6f\xdd\x5f\xe8\x4b\x2e\xf2\x07\x83\x01\x5e\x9a\x0c\xd2\x7c\x9a\x78\x16\x46\x6d\xab\x4a\x46\xee\xc5\xc1\x34\x33\xf5\x61\xa0\x98\xc5\xdd\xc5\x17\xf5\xf5\x70\xc5\x32\x23\x00\x66\x9e\xe9\x6e\xf2\xeb\x8b\x5e\x2b\xa0\x01\xef\x53\x51\xac\x64\x33\x18\xc9\xc5\x66\xce\xc1\x35\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\x0e\xe7\x93\x67\xc6\xcb\xe0\xe6\x71\xa6\x4d\xe8\x14\x5e\x2d\x4d\x50\xed\xa7\x43\x72\x53\xf4\x48\xc1\xda\xf2\x99\x77\xc7\x4c\xb1\x12\xbe\x24\x28\xcf\x12\xd6\xce\x28\xcf\xd3\xc4\xfe\x4d\x8f\x6c\xcc\x17\x21\x65\xcc\x8c\x25\x04\x15\x75\xe5\xee\x8d\x7e\x83\x14\x3b\x85\x98\x13\x4c\x4a\xf9\xc8\xd3\xe6\xd5\xa1\x8d\xcb\x12\x09\xb2\x19\x9c\x6e\x4f\xa5\x09\xa8\x60\xf0\x71\x05\x12\xef\x2d\x18\x21\x70\x87\xea\x36\xee\xc2\xa5\xdb\x3a\xa4\x42\x37\xef\x11\x64\x5b\xa8\xf6\xee\x9d\xef\xf2\xc8\xeb\x26\xbe\x46\xf7\xb4\xf8\x4f\x78\x59\xca\x34\xe9\xfa\xa6\x74\x84\xa1\xcb\x39\x25\x34\x4d\x59\xb8\xd2\x2e\x3b\x4d\xb0\x08\xc8\xa5\xda\x79\x42\xe6\xea\xaf\xcb\xd2\xba\xa7\xf3\xc8\x4c\xc4\x7b\x92\x07\xd8\x24\xaa\x51\x58\x90\x72\xa4\x00\x8c\x53\x58\x40\x45\xed\x16\x36\x47\x07\x4c\x11\x1b\x23\xbd\x73\x2d\x10\xf1\xf0\x6e\x99\x4b\xe3\x81\x74\x18\x26\x0f\x80\x13\x64\x53\x95\x25\x04\xbc\x5f\x1d\x91\x45\x60\x97\x86\x2b\xec\x44\x45\x86\x31\x64\x7e\x0e\x0e\x3c\x40\xb8\x71\x1a\x2d\x35\x4e\x9b\x34\x65\xe8\xcc\x9b\x69\x97\xe8\x09\x78\xc3\x73\x7e\x4d\x49\xb8\x18\xe0\xb5\x6c\x5f\x78\x59\x4e\x4a\x96\x50\x21\x87\x46\x82\xfa\xa6\xbc\xf8\xa1\x9c\x9e\xca\xb0\xb7\x14\x91\xf1\x4f\xb4\x9f\x3b\x3d\x54\x68\x97\x27\x1d\x98\x57\x37\x64\x93\x47\x9a\x8f\xe0\x22\x66\x82\x68\xc9\x50\x30\xee\x17\x2f\x1c\xee\x32\xc0\x30\x29\xad\x8f\x34\x47\xb7\x98\xf8\x14\xff\xdc\x5b\xe0\xcb\x26\xfd\xa3\x9b\x13\xfe\xc7\xaf\xa2\x8a\x76\x48\xf7\x53\x55\xfe\xaf\xff\x40\xd8\x76\x48\x77\x53\x55\xd6\xed\x2f\xdf\xb2\xae\x7b\xfe\xbf\x00\x30\x8e\xe3\x71\x44\x8e\xcd\x3b\x05\x60\x10\x04\x57\xe0\x6f\xbb\x21\x4f\x46\xa6\x99\x7e\xf9\x06\xee\xc0\x1d\x86\x21\x3b\x18\xc1\x8e\xc8\xb7\xff\x40\xf8\xff\x40\xd8\x38\xb9\xb7\x9f\x2b\xe0\xe7\xe5\x33\xe8\xb2\xdd\x3d\x2f\xcb\x5f\xbe\xfd\x07\x8c\xdc\xb7\x7f\xdf\x76\xf1\x2f\xdf\x54\x18\xa1\x76\x38\x92\x41\xc4\x91\x1c\x20\x10\x3b\xc1\x08\xe5\xe0\xc8\x52\x21\xd8\x11\xdf\x81\x19\x82\x1f\x91\x88\x38\x52\x3b\x70\x07\xa1\x47\xec\x48\xed\x20\xea\x88\xef\xe0\x23\xde\x52\x47\x78\x87\x1e\xa1\x1d\x04\x1f\xa1\x1d\x71\x84\x02\x18\x3d\xa2\xd8\xee\xd3\xae\x94\x41\x3b\xfc\x08\xef\x20\x70\x85\x03\x8f\x04\xf6\xd5\x7e\x86\xa0\x23\xf9\x99\x89\x62\x47\x9c\xfa\x6a\xb7\xa1\xc3\xd7\x10\xb5\x83\xf1\x23\x46\x7e\xb5\x9f\xa1\x2f\x84\xe4\x0e\x01\x8f\x18\xf5\xd5\x7e\xcd\xfa\x90\x81\x44\x07\xec\xb8\xa1\x3f\x40\xd0\x11\xdb\xc1\x47\xe2\x00\x51\x47\x64\xbd\xc8\xd6\x2b\xc8\x81\x70\x32\x3b\x40\xc4\x11\xfb\x6c\x74\xc5\x89\x41\x01\x42\x1e\x11\x62\xf7\x69\xc1\x0f\x4e\xe8\xb8\x12\x83\xec\x20\xfc\x7b\xf3\x19\xc0\x8f\xe4\x01\x39\x12\x3b\x08\x39\x22\xe8\x57\xfb\x19\x41\x8e\xd8\x01\x3b\x92\x3b\x98\x5a\x77\xfa\x69\xbf\x90\x1d\x88\x95\x6f\xd8\x11\x27\xbf\xda\xad\xff\xb0\xf6\x13\x3b\x08\x5e\x5f\x9f\x1e\xe4\x88\x1f\xb0\x23\xb6\x83\x88\x23\xf4\xbd\xfd\x8c\xe0\x47\xea\x80\x1c\xd1\x1d\x0a\xad\x1c\xf9\xb4\x5f\x58\xc0\x23\x75\x80\x8e\x70\x76\x80\xc8\x23\xe6\x40\x10\x9a\xad\x17\x4b\x05\x41\xd4\x91\x3a\x60\xd0\x00\x61\x47\x24\x3b\xa0\xd4\x11\x76\x20\x90\xcc\x50\xfc\x88\xac\x7d\x68\x76\x58\x2f\x7f\xf0\x84\x74\x70\x24\xc3\x89\xa5\x82\x57\xb6\x10\xf0\x91\x8a\x8e\xe4\x0e\x3f\x52\x3b\x64\xe5\x01\x74\xa4\x76\xc4\x11\xdd\x41\x58\x0b\x81\x2b\x25\x2b\xed\xe4\x11\x5f\x2f\x02\x04\x3e\xe2\xd0\xee\xd3\x7e\x6d\x1a\xfc\xe2\x20\x0c\x1e\x31\xf8\xab\xfd\xce\x43\xfc\x80\xac\xbb\xfc\xb9\xf3\x2f\xee\xc1\xab\x8a\x81\xe4\x57\x0b\xfe\x90\x3c\xba\x8a\x00\xfa\xde\x7e\xf6\x7d\x24\x0e\xe8\xaa\x93\xf0\x91\x24\xbe\xda\xcf\x00\x7c\xc4\x0f\xe8\x8a\x1e\x5f\x35\xe4\xd3\x7e\x46\xb0\x23\xb4\xb2\x78\x87\x60\xeb\xeb\xd3\x47\x1e\xe1\x03\x7c\x44\xcb\x03\x84\x1c\xd1\x03\x7c\xc4\x02\x92\x3a\x12\xf8\xee\xd3\x7e\xe9\x17\xba\x4d\x24\x76\x08\x72\xc4\xa0\xaf\xf6\x6b\x08\x3c\xa2\x1f\xb1\xc3\x47\xf8\x7b\xfb\x9d\x6c\xe4\x40\xae\xfa\xba\x5a\xca\xd6\x7c\xfa\xe1\xe3\xa6\xb1\xc4\x0e\xc6\xd7\xd7\x97\x4d\x40\x47\xe4\x00\xc3\x47\x74\xb7\x9a\x1d\xf6\xd5\x7e\x8d\xc1\x9b\x5a\xe0\x3b\x1c\x3b\x92\xd4\x57\xfb\x35\x84\xad\xca\x7e\x24\x23\xe2\xb8\x72\x72\xd5\xc7\xd5\x82\xc8\x23\xbc\x5b\xb7\x82\xa0\x47\x14\xdf\x7d\xda\x1f\xeb\x50\x3b\x7c\x35\x0e\xf2\x08\x43\x5f\xed\x77\x8b\xa5\x76\xab\xb5\xa0\x9b\x69\xc2\xdf\xe9\xdd\x21\xab\x58\xa0\xf2\x00\xe1\xeb\x36\x8f\x78\x74\x80\xb6\x3d\xaf\x0a\x49\xac\x0c\x80\x0f\xc4\xba\x25\xe4\x08\xb5\x07\x72\x13\x0b\xb2\x02\x43\xeb\x45\x80\x22\x47\x6a\xb7\x35\x3f\xd4\x15\xdb\x41\xab\x99\x52\x47\x94\xf8\x6a\xbf\xeb\x38\xb9\x43\x8e\x1b\x8d\x38\xf2\xd5\x7e\xb7\x0b\x62\x87\x1e\xf1\xd5\x0f\xad\xda\x81\xfe\xd0\x8e\xc3\x8a\x09\x3b\xa2\x11\xf8\x19\x3f\xc2\xbb\x15\x07\xb1\xaa\x1f\xd2\xae\x3b\xda\x8c\x14\xde\x61\x47\xa4\x5c\xbd\xd8\x0e\x3e\x92\xd1\x6a\xdd\x3b\xf8\x43\xc3\x3a\x84\x6f\x9e\x6b\x9d\x83\xb5\xc4\x77\xe7\xb4\x5e\xc0\xd0\x11\x0d\x10\x68\xf3\x0e\xd0\x77\xef\xb0\x4a\x10\x5d\x61\x90\xd5\x9a\x61\xe2\xab\xfd\x6e\xe9\xe8\x8e\x5a\xf7\xb1\x79\x2e\xe4\x57\xfe\x0b\x5a\x67\xe1\x47\x7c\x87\x6d\xaf\xaf\x4e\x62\x73\x4f\x68\xb4\xa9\xdf\xaa\xbc\xab\x0e\x92\x07\x04\x3a\xe2\x07\xf2\x88\xb5\xab\x27\xa3\x56\x05\x44\x0f\x9b\x1a\xac\xb6\x99\x41\xe4\xf2\x0d\xf8\x3d\xef\x8e\xe2\x54\x12\xc0\x1f\xef\x8e\x80\x9b\xe7\x42\x4b\x12\xdd\xa1\xe4\x11\xdb\x91\xe8\x61\xfd\xdf\xc1\x89\xf2\xf0\x75\x7d\xf8\x1a\x1b\x28\xe2\x0f\x30\xe2\x41\x14\xc4\xd0\x07\x23\x04\x62\xab\x0d\x80\x47\xa8\x3c\xac\xd6\x8e\x1d\xe1\x00\x22\x8f\x10\xb5\xfb\xb4\x1f\x75\x59\x6d\x19\x29\x71\x70\xf5\x1b\x1b\x04\x7a\xc4\xb0\xdd\xa7\xfd\xd2\xc1\x75\xd3\xe0\x06\x72\xf8\x23\x24\x07\xe4\x88\x28\x10\x8c\x6c\xcb\xfd\x16\xc7\x87\x71\xe0\x52\x7d\x36\x00\x7f\x27\x08\x5f\x41\x09\x64\xf7\x69\x3f\xa0\xab\x8f\x82\xb0\x72\x15\x29\x18\x40\xd8\x11\x23\x76\x9f\xf6\xb3\x14\xbc\x0a\xfc\x88\xff\x9a\x9c\x7f\x46\xb1\x23\x8f\xf8\x01\xc2\x1c\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\x0e\x01\xaf\xb2\xf8\x9a\x51\x6d\x26\x8c\x94\xbf\x52\x9d\x7f\xd6\xb0\xe1\x40\xfd\x54\xb1\x7f\x93\x18\x6a\x07\x21\xeb\x11\x76\x84\x69\x08\x3b\xe2\x2b\x4f\xd6\xf6\xc3\x00\x8a\xdc\x41\xeb\x19\x3c\xac\xe3\xc1\x6f\xc7\x21\x6c\x75\x44\xd8\x91\xc8\xfe\x78\x7c\x6b\x86\xdf\x1d\x3f\xfc\x18\x5f\x2a\x70\x87\xa3\x47\x2c\xfb\xb1\x10\xb6\xfb\xb4\x5f\xde\x66\x75\x2d\x64\xb9\xb1\x62\xf5\xb1\xeb\xc5\x7a\x82\xfc\x01\xe8\x81\x5c\x2a\x72\x3d\xd9\x56\x46\x64\x87\x55\x3b\xff\x69\x6d\xf0\xf0\x1b\xda\x20\x64\xf7\x69\x3f\x4a\x06\xef\x88\x23\x5e\x7e\x2d\x84\x38\x10\x4a\xae\xda\xb6\xbd\xa5\x56\xf0\xf5\x40\x3e\x7e\x3f\x13\x37\xe0\xdf\xdd\x24\xf8\x93\x09\xd9\x11\x77\x70\xe2\x08\x2b\x10\xb9\x1e\x4a\x18\xb5\x54\x07\x9c\x3a\x92\x07\x14\x5c\xe5\x0c\x82\x6b\xd8\xb5\xe1\x26\x36\x52\x88\xef\xa4\x7c\x76\x7f\x84\xb2\xdf\x65\xce\xee\xb3\xe3\xf2\xf0\x9d\xd6\x45\x45\x57\x9f\x8c\x91\x47\xea\xd3\xb9\x23\xd7\xc0\x03\x3f\x22\xd9\xef\x71\xe2\xa7\x14\xbf\xc4\x8c\x6f\xa7\x00\xfe\xf3\x14\x58\xcf\x19\x62\x59\x1d\x1b\xb5\x83\x50\x72\x65\xe8\x8a\x0e\xfe\x2e\x0f\xe4\x9f\xf9\xb1\x5b\x67\xe0\xc3\xef\x6a\x15\xb8\xfb\x8e\xe7\x0f\x34\x14\x24\x91\x10\x43\xbf\x6d\x1d\x87\xe6\x19\x44\x79\x37\xff\xf2\x0d\x3c\x42\xd8\x3f\x98\xd0\x7a\xba\xac\x0a\xbf\x3a\xc5\xef\xfa\xbf\xbe\xfb\x2f\x62\x05\xbf\x63\xa5\xc8\x2d\xda\x41\x8e\xe4\x77\x33\xda\xfd\x16\xe7\x9a\x0b\xac\x57\x20\xfd\x3f\xfe\x3b\x59\x4a\x95\xc7\xff\x90\xa4\xfc\x57\xa7\x17\x7f\xf4\x9c\x90\xdf\xc9\x71\xfe\xbf\x28\x0b\xde\x6d\xd2\xfd\xd2\x77\x77\xf2\x7b\xc2\x93\xc7\xbf\x7c\x53\x82\x39\x79\xff\x27\xfc\xed\xbf\x9c\xfd\x10\x6b\x3e\x00\x7e\xa5\x3e\x6d\x37\x97\xc9\x17\x77\xca\xbc\x4e\x82\xb7\xf8\x0e\xe2\x3c\xa9\xbb\x6d\x11\xcb\x11\x25\xee\x3f\xa1\xff\xfc\xb6\x4b\xbf\xba\xed\x3a\xef\xda\x5f\xbe\xf5\x6d\xf2\xb6\x9e\x41\x94\x5c\x6a\xbb\x4d\xbe\xed\x26\xe8\x97\x6f\x6b\x5a\xf0\x6d\x37\x43\xbf\x7c\x83\x40\xe8\xdb\x6e\x82\x7f\x74\xad\x57\x47\x70\x95\xd5\x77\x34\xd7\x77\x50\xb7\xf7\xe6\x5d\xfd\xf2\xad\x0a\xba\x77\x3e\xfd\x3f\x9f\xb0\xe9\x00\x6d\x31\x30\xfc\x3f\x7f\xd0\xd7\x3c\x77\xcd\xfd\xbe\x72\xe0\x1b\xf8\x6d\xb7\xbe\x3f\x44\x4d\xd9\xbc\x37\xb5\x48\xe0\x28\x4e\xd0\xef\xe2\xfd\x07\xe0\x23\x44\xfc\x16\x1c\x8c\x82\x04\xfe\x7d\x70\x04\x42\x7e\x03\x1f\x87\x11\x18\xc7\xbf\x0f\x8f\xa2\xbf\xc5\x1f\xc3\x21\x14\xff\x01\x39\x18\x81\xfd\x06\x3e\x22\xa8\x38\x22\x7e\x1f\x1e\xa7\xc8\xdf\xc0\x87\x01\x89\x86\xd4\xef\xc3\x93\x10\xf5\x1b\xf8\x20\xc4\xc9\xe0\x0f\xe0\x29\x04\xfd\x0d\x3c\x15\xa1\x18\x45\xfe\x2e\x3c\xf4\x5b\x60\x04\x0e\xc8\xe4\x87\x69\xfd\xa3\xf6\xfc\xca\x86\x57\xf3\x44\xb7\x1c\xa5\x5c\x83\x3e\xfc\x48\x38\x14\x75\x5a\x93\xaa\x0c\xc5\x96\x6f\x5f\x36\xbe\xaa\xff\x7f\xc0\xc8\x77\x85\xfb\x9f\xff\xe0\x06\xfe\x1d\x14\xbf\xf2\x0a\x2b\xa9\xef\xa6\x48\x36\x32\x49\x12\x46\x48\xe4\x7b\xd7\x61\xcc\xe3\x2e\xfb\xe5\x1b\xfc\x1b\xfc\xc4\x11\xdb\x51\xd0\x11\x72\x88\x35\x29\xc4\x8f\x50\xb9\xa6\x3c\xd0\x9a\x70\xad\xe9\xe5\x7a\xb1\xf6\x3a\x14\x94\x1d\x90\x23\xe9\x10\xd8\x9a\xfd\x6c\x6e\x13\x5f\x7b\xa8\xf2\x80\xae\x6e\x18\x77\x28\xe8\x44\xac\x89\x24\xbc\xce\x05\x3f\xf8\x50\x87\x04\xcb\x35\x67\x22\x8f\x64\x86\x1d\x51\x05\x5d\x63\x69\x82\x2a\x3f\x51\x73\xb6\x26\x71\xe5\x9a\xc3\x1e\xa8\x23\xb2\x65\xac\xc8\x11\x19\xf0\xec\x80\x2e\xd5\x1a\x27\xef\x40\x05\xa5\x76\x04\x74\x44\x32\xf4\x88\x2a\xd8\x16\x36\xe0\x25\xfa\x09\x72\x89\x0c\x5d\x43\x0b\xe2\x93\x08\x92\xd9\x9a\x41\xfc\xe0\xec\xa7\x7a\xf1\xed\x5f\x19\x39\xfc\xef\x19\xf9\x9a\x23\x7d\x8c\x1c\x03\x8f\x20\x8c\x7c\xec\xfc\xab\x17\xfe\xd9\xfb\xdf\x32\xf4\x8f\xaf\xf8\x67\x7d\xc3\x11\x94\x82\xfe\x4d\xe5\x24\x40\x08\xc1\xc3\xff\xad\x72\xfe\x21\x27\x90\x7f\x93\x13\xd0\x11\x83\xa0\x2f\x5e\x40\x47\x02\xc2\x3f\xbc\xc0\xb1\x23\xbc\xf5\xc3\x3f\xfb\xff\xfa\xdc\xf8\x61\x07\xf8\x7a\x3c\x63\xd8\x11\x5b\xf3\x55\xe2\x70\x84\x57\x6d\x3c\x1c\x91\xad\x0a\x70\x44\x0e\xc4\x11\x39\x7c\xd2\x56\x64\x8d\xcf\x0f\xd0\x96\xab\x1f\x09\x0b\xa6\xd6\x54\x7b\x35\x1a\x78\x1d\xc3\xd1\x68\x9d\xb9\x65\xb9\xc8\xe1\x93\x96\xad\x19\xe0\x61\x8b\xca\x91\xc3\x56\x10\xc2\x0e\xd0\x61\x0d\x5f\xb6\x44\x9d\x38\x6c\xf8\xd6\x55\x57\xb8\x35\x55\x39\x92\x87\x23\xb5\x83\xbf\x4a\x22\x2b\x21\xd0\x71\x2b\xa6\x1c\xa1\x2d\x55\x27\x8e\xf8\x6e\xcd\xdc\x89\x23\xf4\x29\x2e\xe1\x87\x23\xba\x83\xd7\xfc\x16\xdb\xe1\x6b\x3e\xfd\xa9\xb6\xad\xd9\xe1\x66\x1b\xeb\x05\xbe\x21\x3a\xc2\x6b\xe6\x7e\xf8\x54\xc7\x90\x1d\x58\x1d\xa8\x35\xae\xc1\x8e\x48\x74\xc4\xb6\xee\x6d\xbf\x3b\x68\x03\xda\xd8\x40\x7c\xb6\xbf\xa2\x85\x8e\xf0\x01\xdf\xba\xd7\x44\x73\xb5\x42\x62\x07\xaf\xef\x77\xe8\xee\x88\xae\x49\xf0\x3a\x15\xde\xa1\x1b\x05\xc4\xb6\x25\xec\x53\x91\x80\x8f\x44\x05\x6f\xb5\xb7\x0c\x3a\x42\xd1\x4a\xca\xca\x25\xe8\x83\x6d\x2b\x4a\x61\x2b\x43\xb6\x9a\xde\xa7\x98\x76\xa4\x96\x0a\xd9\xe8\xc8\xa0\x23\xe6\x20\xe4\x1a\x68\x23\x11\xb8\x5b\x59\x87\x7e\xed\x62\x0d\xc3\xd1\x1d\xb8\x51\xbf\xce\x05\x3f\x5c\xda\x84\xf7\x6b\xfc\xdb\xdc\x61\x03\xdf\xea\x7d\x6b\x5c\x49\x45\xbf\x01\xdb\xaa\x15\x1b\xc3\xb7\xfa\xc0\x87\x93\x2b\x21\x87\x75\x87\xd1\x91\x38\xae\xf9\xd5\x46\xdd\xca\xae\x35\x5a\x24\xa2\x0f\xed\x1f\x29\xe1\x9b\x10\x3e\x53\x36\x0f\x7a\x84\x56\x8a\xf1\xc3\x86\x08\xfd\x90\x7c\xc4\x8e\x9f\x29\x1f\x76\xc3\xdb\x0b\x5f\x35\xe5\x83\x86\x5a\xf7\xb2\xea\xcc\x3a\x4a\x1d\xd1\x15\xd7\x4a\x33\xb9\x11\x0c\x6d\x5b\x5c\xe9\x43\x76\xe0\x61\xf5\xb6\xab\x6a\xae\x64\x6d\xf4\x1e\x56\x22\xd7\xdd\x7e\x57\x84\x23\xb4\x54\x30\xb9\x2a\x1f\x1a\xad\xdb\x45\x3e\x62\xde\x58\x45\x1d\x57\x79\xe2\x9f\x1d\xfd\x21\x29\xc8\x47\x58\x2b\xe2\x6d\x5b\x9f\xc2\xc8\x87\xe5\x5f\x62\xf8\x0e\x42\xae\xd3\xb6\xce\x95\x1d\xd9\xe1\x48\x7d\xd6\xfc\x90\x8d\x1c\x36\x05\x86\xb6\xb2\x21\xb5\xd5\xa2\xb6\x0a\xd7\x56\x31\x5b\x07\xb7\xc3\x60\xc5\xb3\x9e\x3f\x6b\x60\x4e\xac\x18\xb1\x1d\xf4\xd1\x7c\x74\x2b\x18\xe0\x5b\x19\x87\x3c\x22\x2a\xf2\x55\xe5\xc4\xa3\x23\x76\xdc\x6a\x34\x9b\x36\x6e\x2c\xfe\x62\xd4\x87\xbc\x95\xd9\x9b\x34\xa8\x95\x38\xf8\x23\xac\x95\x49\xab\x64\x8f\x9f\x3c\x88\x8a\x8e\xd4\x06\x0c\x7f\xe6\x6c\x9b\xf8\xc9\xcf\xcd\x2b\x6c\xc4\x62\x5f\xfc\x85\x3e\x76\xb9\x54\x07\xec\x88\xac\x34\x6c\x47\xdf\xea\x1f\x56\x73\x5c\x8d\x73\x55\xc9\x8f\x98\xb1\x1f\xc8\x0e\x9b\x5c\xe0\x1f\xd8\x36\xb9\x1d\xa9\xad\xf7\xc3\xe0\xf5\x50\x86\x4f\x10\x11\x6d\x03\x1f\x39\xfc\x84\x47\xb7\x75\xe1\x0f\x1a\x64\x95\xde\x86\x79\xf7\xdd\x47\x6c\x56\x83\xee\xa0\x68\xcd\xcd\x57\x01\x6d\x75\x3a\xe8\x88\x7e\xa5\x64\xbb\x15\x76\x25\x1e\x3e\x6e\x15\x35\xf8\x80\xae\xd4\x61\xeb\x69\x7e\x84\xb6\x9a\xdc\xca\x1a\xf8\x63\xeb\x1f\x6f\xb7\xb2\x76\xb3\x93\xd5\x5b\x20\x4b\xb5\x4e\x20\x7f\x18\x32\xf6\x91\x36\xbc\x95\x53\xa1\xd5\xd2\xb0\xe8\xb3\xfb\x9f\xbc\xd8\x98\xb4\xb9\x88\x68\x2b\x3e\x6e\x94\xa3\x1f\x63\xdb\x56\xdc\xb0\xac\xa2\x3d\x6c\x88\x3e\xda\x84\xae\x2c\x5d\xed\x60\x65\xfe\xe7\x3f\x6c\x53\xa3\x2f\x75\xf8\x58\xde\xba\x0c\xb6\x2d\x83\x6e\x21\x04\xf9\x41\xb7\x52\xb0\xca\x98\xda\x6d\x6e\xf2\xb8\x55\x51\xb7\xf9\xf0\x0e\xfd\xae\xb4\x5b\x5d\x78\x33\x1b\xf2\x53\x38\xf9\xe4\xe2\xab\x57\x43\x0e\x9b\xdb\xc6\x3e\x46\x48\x1d\xc9\xed\xf3\x0c\x6c\x73\xfc\xf8\x4a\xe2\xaf\xe8\x3c\xfc\xd8\x2f\xf1\xa5\xe2\xab\xdf\xfc\xec\x09\x3d\x52\xd5\x96\xdc\x22\x9b\x27\x83\xa2\x75\xdd\x8f\xd7\x81\xbe\x9b\xc9\x4f\xe7\xb4\xee\x09\x1d\x56\x47\xb7\xee\xe6\x83\x6e\x75\x29\xe0\xb0\xf1\xf5\xb0\x2d\xfd\x61\xf6\xba\x6b\x78\xa9\x88\xcd\x17\xa0\x19\xf4\xa9\x79\x60\x1f\x37\x79\x84\x3e\xca\xb8\x29\x24\xb6\x79\xbd\x03\xb4\xe2\xfd\x15\x09\xe8\x77\xb5\xde\xfe\xfb\x8d\xcb\x59\x65\xb7\xe2\xf9\x72\x0f\x1f\xf5\x22\xd6\x4d\x7f\xed\x8c\xfa\xee\x30\xb0\x0d\x15\x79\xf8\x8e\x71\x63\x2d\xfe\xd1\xeb\x8f\xcb\x40\x77\xeb\xe2\xd8\xc7\x83\xe2\x1f\x9b\x40\xfe\xb7\xd3\xc9\xcf\x74\x74\x51\x21\x6c\x87\x11\xd1\xaf\x85\x4f\x6c\xc6\xb0\x8a\x6f\xa3\x79\x53\xd2\x8d\xed\xc8\xe6\x59\xb6\x03\x24\xfa\xc8\x04\x3d\x92\x1f\x0e\x7e\x3e\x9b\xda\xdc\xdb\xee\xf3\x81\x0d\x71\xf8\xd2\x5e\xf2\x33\xe3\x43\xea\x7a\xc0\x46\xd0\x77\x58\xf2\x0b\x96\xfa\xe1\xca\xd0\x5f\xb9\xb2\x9f\x7e\x7e\x93\x19\x11\x7d\x77\xf4\xc8\x0f\xb7\x43\x6e\x12\xdb\x6d\x64\xe3\x9f\x13\x0e\x59\xdf\xaf\x6a\xff\x9d\xd7\x2a\x84\xef\x70\x70\x75\x86\x5f\xd6\x00\x1f\x36\x0f\xb3\xae\xbb\xaa\xed\xe7\xd4\xdf\xfd\x38\x15\xa1\x4f\x88\x10\x6d\x12\x3e\x42\x5f\x6e\x0b\x59\xf7\xf1\xd3\x7d\xad\xbb\xfb\x3a\x9f\x36\x2f\xbe\xae\xff\xd9\xca\x91\xfc\xee\xf5\xd6\xa3\x89\xfc\x07\xe7\xb1\x9d\x28\xdf\xfb\x56\x5b\xdc\x34\xe5\xeb\x68\xd9\x74\x8e\xfa\xa2\x10\xda\x6d\xd8\x56\x15\x54\x21\x6a\x87\xc3\x1f\xf5\x5b\x97\xdb\x8e\x24\xfc\x23\xce\x8f\x90\xa1\xaf\x13\xe7\xe3\xa3\xbf\xb6\xb1\x1a\xd3\x6a\x11\xc8\x77\x47\x87\x1c\xbe\x0e\xa1\xef\x07\xf6\x26\xc3\x2f\xa7\xfc\xc5\xee\xdf\x4d\x9d\x90\x9f\xa9\xd3\x1f\x06\xb8\xe8\xbf\x17\xe0\xae\x19\x17\x4e\x7d\x02\x5c\x02\x3d\xc2\xe0\x57\x80\x8b\x91\x47\x62\xeb\x87\x7f\xf9\x46\x12\x47\x02\xfc\xef\x06\xb8\xbf\xcd\xeb\xef\x54\x72\xbf\xe3\x7f\x90\xa8\x13\xbf\x4d\x8c\xef\x64\x12\xdf\xb1\x3f\x48\xbc\xa1\xdf\x46\xcf\x77\x24\xc1\xef\xbf\x1f\x3d\x1f\x71\x08\xfe\x6d\xe1\x20\x8a\xc3\x24\xfc\xa3\x44\xfd\xb7\xe0\x48\x14\xfd\x51\x9d\x81\xc0\x7e\xa7\x6e\x40\x84\x64\xfc\x07\x75\x00\xf2\x77\xea\x18\x51\x10\x40\xd1\x1f\xd5\x01\x88\xdf\xc6\xff\x61\x44\x92\xe1\x1f\x90\x4f\xc1\xbf\x85\x0f\x12\x3c\x0a\xfe\x08\x1e\xff\x9d\x64\xe4\x8e\xc6\xd4\xef\xc3\xff\x99\x75\x83\xec\x00\x13\x0e\xf4\xfb\x7a\x8f\xfe\xcb\x92\xc1\x3f\xcc\xfe\xaf\x56\x0b\xbe\x77\xac\xd4\x3e\x9a\xbc\xfe\xe5\x5b\x98\x0c\x49\xf9\x4f\x85\xc5\xff\x5e\x55\xb1\xf9\xbb\x2c\xf8\x77\x59\xf0\xef\xb2\xe0\x5f\xab\x2c\xb8\x66\x58\x7f\x5a\x59\x10\xdf\xf2\xbd\x35\xea\xa3\x8e\x64\x04\x1e\xe0\xdd\x56\xec\x23\x8e\xd4\xe1\x93\x07\x43\xdf\x63\xac\x2d\xe9\x5a\xe3\x1d\xf2\x13\x78\xad\xd1\xfb\x1a\xd6\x7f\x95\x05\x3e\x79\x21\xbc\x86\x1f\xe4\x0e\xdd\x62\xc4\xdd\x1a\x4b\xad\xd9\x17\xb5\x23\xb6\x8f\xe9\x89\xcf\x0d\x43\xdb\xcd\x07\xc4\x0e\xfd\xdc\xcf\xb3\x23\xb6\x18\x0c\xd9\xc2\x8c\x1d\xb6\xc5\xf7\xf8\xee\x93\x23\x6c\xc0\x07\xf4\x33\xf9\xf0\x85\xa4\x5d\x93\x95\x35\x24\x21\x3e\x79\x52\xb4\x85\xa7\xeb\x1f\xfc\x75\xcb\xc2\x07\x18\x5d\x2a\x74\x8b\x58\x22\x70\x2b\x84\x60\xbb\x35\x88\xc2\x77\xdb\x9d\x45\xbb\xef\x39\xeb\x1a\x34\x6f\x6d\xbb\x85\xcc\xf8\x56\x1f\x21\xa2\x2d\x8d\xdb\x42\x57\x78\xdb\x3a\xbe\xdd\xd3\x02\x7e\x02\x5b\xec\xf0\x49\x6e\xd6\xec\x03\xda\xc2\x22\xf8\x13\xf9\x6e\xfd\x44\x7b\x40\x76\x47\xfc\xb0\x61\x8d\xbe\xd2\xfc\x2d\x8c\xdf\x6d\x40\xbb\x2d\x31\x80\x37\xa1\x81\x5b\x89\xf4\xb0\x95\x48\xbf\xaa\xa8\xc4\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\x7f\x57\x51\xff\xae\xa2\xfe\x5d\x45\xfd\xbb\x8a\xfa\x77\x15\xf5\xff\xc2\x2a\xea\x13\xf9\x6b\x7d\x2b\xbd\x9e\x7e\xfe\xc0\x12\x49\x7d\x9e\x46\xfd\x0e\x08\xcf\x9d\x9e\x56\x2b\xf8\x52\xe8\x18\x77\xca\xe4\x05\xe6\x54\xf8\x8c\x29\xe9\xe7\x0c\x1d\xdf\x1a\xc2\xb5\x37\x54\xd5\x45\x9d\x0c\x81\xd1\x66\xa5\x13\x3f\x62\xbc\x0f\x8e\x20\xda\x50\x92\x12\x99\xbc\x58\x8d\x4e\x1a\x78\x61\xe8\xc5\x75\x0c\x87\x9e\x36\xe9\x41\x26\xce\xd1\x92\x84\xdd\xf2\x5e\x90\x21\xa1\x28\x02\x05\x5d\xd3\x3c\x15\x6e\x8d\x45\x49\xd8\xa3\xd1\x09\xb7\x54\x9f\x48\xc0\x87\x49\x9f\xde\x54\x84\xb8\x53\xeb\x0c\x51\x52\x55\xe1\xdc\x52\xf3\x15\xdf\xf7\xa7\x33\xd9\x04\x7a\x72\x9f\x9f\xb1\xce\x71\x98\x5f\x65\xd8\x08\xe3\xa3\x5a\xf0\x59\x43\x9e\x3b\xae\xeb\xf9\xcb\x4d\x60\xdf\x83\x06\xa0\xfd\xf9\xa6\x89\x27\xf0\x8a\x51\x1c\x46\x7a\x00\x0b\x13\x81\xa0\xd1\x0a\xe2\x75\x59\xd5\x8e\x23\x26\xb2\xb3\x86\xee\xfb\xa5\xdf\x5f\x94\xce\x68\x6d\x7d\xd2\x8d\x09\xbf\xa9\x74\x63\x3c\x18\x7a\x24\x2e\xfb\x90\x77\x58\x55\x35\xd2\xd7\x9c\xb6\x7b\x45\x68\xa1\x6c\x1f\x8b\x31\x19\xd6\x01\x68\x54\xde\x85\xba\x28\xf8\xd9\x4f\x47\x7a\xb8\x08\x37\x59\x6e\x66\xc4\x41\x51\x36\xd5\xee\x03\xe1\x4f\x64\xa3\x9c\xf6\xa5\xcd\xa7\xc3\x22\x90\x7e\x9c\x2d\xfb\x1a\x85\xda\x9a\x16\x4d\x11\x4b\x6d\x7e\x64\xcb\x25\x3b\xc5\x43\xd7\x09\xd3\x5d\x9b\x7d\x19\xe4\xeb\x73\xb3\xc8\x32\x96\x88\xd1\x1d\x7a\x9d\x1a\x48\xbc\x4c\xdd\x63\x94\xf6\xcf\xfb\x50\xa1\x29\xe0\x42\xaf\xee\x9c\x26\x6f\x9f\x87\x2d\xef\x6c\x49\x0a\xb5\x77\xc1\x47\x01\x56\xac\x95\xd1\x13\xe7\xa5\x86\x9c\x86\x9a\x37\xdd\x5e\x08\x36\x18\x32\x9b\xcb\x46\x61\xd9\x5e\x1c\x41\xfb\x34\x8a\x32\x48\x38\x89\x7a\x25\xf7\x52\xca\xb0\x71\x84\xe3\xaf\xb3\x71\x52\x45\x6a\x0f\x69\xd2\xd3\x9e\xcb\x69\x3a\x75\xbd\x8b\xa7\x7c\x7e\x95\xfa\xbd\x86\xce\x8f\xd8\x4d\xbb\x19\x9c\xaf\x55\xac\x3d\x84\x25\x1a\xe5\x87\x0f\xaa\x36\xa1\x2a\xdd\x5e\x7a\x34\x56\x10\x43\xb8\xd0\x48\x13\x12\x02\x34\xc8\xdd\x08\xc1\xf7\xea\x36\x7e\xd2\x0f\x5b\xe5\x2e\x0f\x09\x5b\xf4\xf4\xde\x30\xad\xd9\xc4\x59\x26\x66\xb7\xd3\x9d\x61\x6c\xa0\x16\x69\xd1\xec\x26\x57\xba\xa4\x58\x79\x85\xb5\xee\x2d\x61\xb1\x02\x5a\x0c\x26\x9f\x17\xa5\x89\xcb\xe6\xe5\x05\x17\x3e\xe8\x74\x71\xe9\xe4\x17\x96\x8a\x88\x85\x71\xda\xa3\xa7\x65\x4c\x7b\xc8\xe7\xbb\xee\xcb\x12\xd8\x14\x4c\x61\xc5\x49\xc5\xe6\x56\x6a\x01\xef\xc2\xd0\x14\x2b\xd1\xbb\x89\x79\xa0\x8a\xc5\x8e\x77\xa1\xe3\xc1\xe2\xfd\x7a\x79\xc4\xcd\x51\xeb\x9e\xf2\x4a\xd5\x9b\xe1\x92\x50\x79\x30\x5e\x68\x24\xa7\x35\x63\xf6\xf1\xc1\x9d\x58\x1c\xb2\x7d\x14\x5a\xae\xb3\x16\xf9\x19\x0e\x18\xac\xe6\x19\xc3\x92\x63\xb1\x89\x50\xf5\xc9\x79\x41\x8c\x3d\xf7\xaa\x48\xd3\x66\x2b\xe0\x5d\x18\x26\x68\x2e\x73\xd0\x9b\xb8\x54\x58\x2e\x30\x71\xe5\x42\x56\xcb\xdd\x4b\x25\xef\x19\xbc\xf5\x28\x70\x4f\xd3\x06\x77\xa2\x5d\x22\x76\x41\xbf\x5e\xd2\x3f\xf7\xd1\x36\xd5\x13\xfd\x8b\xf9\x0e\xe6\xc7\xa3\x6d\x0a\x8a\x7a\x83\x10\x6d\x4f\x04\xf5\x6c\xdf\xd7\x77\xff\x70\xba\x30\x4a\x82\xb0\xbe\xb5\x28\xe7\x9b\x27\xab\x51\x33\x9c\x4b\x5f\x04\xf1\xae\xf7\xf4\xbd\xa1\x81\xbd\x74\x47\x99\xa6\xd8\xb3\x20\x7b\x9f\x1c\x93\x63\xb2\xbd\x04\x6b\xaf\xdb\xf2\x7e\x5a\x10\xe7\x0c\x61\x67\x23\xd6\x59\x8f\x2a\xd2\xb2\xca\xf6\x5c\x26\x51\x5b\x53\xf1\x95\x40\xea\x0b\x89\x39\x00\x43\x9d\xc0\x13\x41\x5e\x94\xb8\x03\x14\xae\x34\xa0\x5e\xf5\xe7\x50\xa2\x53\x89\xaa\x29\xea\xe2\x4e\x4d\x42\x22\x75\x91\x2f\x54\xc6\x71\x41\x82\x20\xe0\x79\x98\x14\x94\xbc\x60\x90\x37\x55\x40\x52\x6b\x9d\xac\x87\xce\x48\x67\x20\x1f\xe1\x85\xff\xf4\x82\x8e\xd2\xeb\x12\x16\x19\x16\x84\x4f\xef\x87\x8a\xf9\x44\x86\xea\xe4\x9e\x10\x3a\x49\x70\xce\x28\x75\x79\x4f\x76\x5d\x12\x7d\x24\xc5\xf7\x6c\xd8\x33\x12\x37\xec\xef\x4c\xf4\x20\x9e\x40\xe7\xa9\xfa\xbb\x85\x4d\xcf\xb9\x8e\xe8\xc5\x83\xed\x5a\xb8\xbe\x3d\x36\x0c\x7d\xa2\x7b\xaa\x2d\x0d\x21\x02\x67\x71\xf4\xc5\x40\xd3\x33\x2f\xda\x67\xa5\x05\x75\x3d\xa3\xd8\x82\xb7\x5a\xfd\x5d\x4d\x13\xbf\xc0\xe5\x3b\x40\xde\xf5\x93\xee\x10\x11\x0f\xe2\x34\x36\x32\xe6\x59\x25\x4a\x21\x34\xb1\x56\xb5\x8f\xe7\x45\x6f\x3c\xe6\x6d\x5c\xb9\xa8\x12\x04\xcd\x22\x72\x44\x35\xb9\x65\xd1\xd9\x11\x18\x86\x80\xcc\x0b\x7b\xcf\x5e\x8c\xa9\x82\x50\x86\xc9\x86\x73\x74\x52\xc4\xa7\xa8\x5f\x2f\xf4\x79\x9a\x12\x25\x7c\x9b\x29\x5d\xf8\xfd\x83\x89\x4f\xa8\x88\x35\xee\xd9\xf5\x6c\x17\xa2\x7c\x05\xf5\x5e\x7d\x4d\xab\x42\x56\xbf\x20\xe6\xe5\xfa\x69\xe0\x43\x2a\x7d\xa2\x2d\xe3\x92\xdb\x14\xbe\xc8\x4b\x61\x13\x78\x35\x26\x59\x70\x19\x26\x3c\xa3\x7a\x75\x20\x64\x41\x43\xcc\xe6\xa9\xa0\xcd\x95\x96\xd0\x93\x99\xa1\xa3\x55\x22\x14\x35\x95\xc1\x1e\x04\xfd\xd0\x44\xe6\xb7\xb4\xa8\x94\xb5\x58\xaf\xf4\x7c\xae\x1b\x39\x2a\x4a\xf1\x7d\x02\x49\x36\x3a\x3f\x6a\xa6\x53\x14\xb6\xb5\x78\x51\x7c\x5a\xee\x79\x38\x75\x9c\xac\x35\x42\xfe\x7c\xb6\x67\xb0\x2f\xa5\x96\xe3\x6c\x96\xa5\xaf\x6a\xc9\x18\x85\xd6\x07\x19\x3f\xe7\xb7\x6b\xa4\xb4\x95\xc0\xc8\x81\x31\x05\x97\x02\x43\xae\xe5\x29\x91\x0b\x95\x00\xe9\x07\xdd\x34\x6c\x9a\x31\x97\x82\x6a\xe5\x4e\x1a\x5e\x9d\xfe\xb2\x50\x81\x09\xcc\xfa\x6c\x99\x1e\xd9\x3d\x60\xee\x92\x21\xa5\xc0\x60\xc6\x08\xdf\x34\x41\xc6\x14\xb3\xc1\x47\xb4\x95\x3b\x38\x4d\xe9\x65\x1e\xf3\x98\x56\x35\x80\xea\x25\xdd\xba\xa5\x25\xa3\x70\x17\x4c\x10\x90\xca\xe4\x90\xf1\xc4\x53\x2f\xc7\x1c\x9a\xd3\xdb\x7e\xde\xeb\xbd\xcd\x1b\x32\x08\x10\x56\xd6\x8d\x61\x73\x3a\xe3\x8f\xf8\x44\x9a\xb7\xc9\x62\x31\x22\xb3\x1c\xfe\x1a\x12\x09\x06\xc0\x3d\x28\x4c\x2f\xfd\x74\x6e\xc6\x3d\x99\xdf\xd0\xd2\xf7\x61\x43\xec\x91\x3c\xce\xa4\xe9\x42\xf8\xc4\x93\xa4\xe9\x91\x56\x58\xf1\x26\xf3\x3a\x23\xb2\x7f\xba\xaf\xf8\x8b\x3d\x75\xf7\x67\x9c\xd1\xfe\xf8\x21\xc7\x3e\x34\xe3\xf2\x55\xd5\x36\x13\x36\x01\x68\x27\xb6\xc1\xe5\xb6\xc8\xb2\xd0\xfe\x5c\xbd\xb3\xa9\xf1\x3a\x20\x65\x06\xef\x9c\x13\xa8\x74\x47\x69\x07\xf4\x91\x56\x93\x05\xd0\xb7\x03\x89\x7d\x35\xd2\xfd\x91\x3a\x56\xc6\xe7\xa2\x80\x76\xdc\x25\xbe\x00\xf7\x4b\x72\x09\x2c\xb9\xcb\x13\x4c\xbc\xf5\xc4\x73\x59\x90\x04\x88\x88\xa5\x93\x45\x29\x90\xd0\xa1\xa6\x9e\x7b\x40\x47\x32\x34\x41\x03\x5c\x1f\x70\xbe\x31\x18\x2e\x9f\x09\x1d\x7b\x47\x90\x0e\x79\x1d\xee\xe9\xa4\x8a\x25\x0f\xaf\xc1\xed\xf3\x3e\x76\xc3\x3e\xa9\x92\xab\x18\x3f\x07\x2d\xce\xb5\x84\xf2\x07\x43\x49\x50\x26\x47\xf5\xea\xfa\x34\xab\xf9\x45\x56\x04\xf4\x7e\x12\x28\x33\xc9\x02\xdc\x8d\xd2\x69\xa0\x9b\xfd\x1d\x28\xa1\x2b\xec\x3f\xc1\x25\x4a\x4e\xf9\x72\xbf\xdc\x02\x60\x32\xeb\x3b\x63\x66\x22\xca\x1a\x2f\xda\xcf\x1b\xc6\x4d\x3c\x6e\xa6\x49\x2e\xc7\x93\x1c\x8a\x12\x8f\x85\x3c\x66\x7c\x5f\xbd\x93\x7e\x82\x07\x17\x8f\x22\x86\x61\x54\x09\x67\x5a\xcb\xe6\x8d\x25\x28\x44\x05\x9f\x18\xb0\x1b\x1e\x33\x33\x99\xda\x14\xb3\x5d\x04\x7b\x77\xd2\xa4\xae\x73\xe0\x5e\xb9\x4b\x0a\x5f\x1f\x77\x27\x1e\xf1\xec\x25\x35\x3c\xc5\xc0\xe2\x54\xf0\x9c\x5b\x2a\x27\xa2\x45\x93\xae\x4b\xe0\xc2\x7a\x82\x0d\x67\x26\xcb\xdb\x18\x59\x49\xa2\x91\x46\x3c\xbd\x41\xa0\x92\xd5\x8a\xc7\x90\x57\x03\x23\x2e\xba\x1f\x31\x6b\x6f\x60\x4d\xd6\x84\x94\x87\x74\xe9\x29\xbd\x90\xb6\x62\xd0\x2c\x4b\xa4\xea\x44\x55\xb2\xa1\x23\x20\xef\xe2\x15\x7f\x7a\xfa\x39\x39\x45\x67\x3e\x5e\xd4\x3e\x7a\xdc\x0b\x39\x7a\x5f\xef\xd5\xab\xca\x05\x9f\x99\x58\x01\x90\xe2\x7d\x1a\xcc\xf2\x79\x6c\x8c\xc7\x29\x7e\xd3\xd8\x80\x9e\x64\x82\x7d\xa1\xa8\xfc\xb8\x69\xee\x33\x48\x83\xd7\x93\x30\x68\xb6\x68\xc1\x13\xb5\xd4\x2e\x82\x63\x79\x00\xa3\xdc\xd2\xf0\x5c\xb3\x5c\xce\xe1\x89\x4c\x9c\x4e\xb4\x32\xef\x74\x1d\xb5\x77\x10\xd5\xad\x48\xbc\x70\x65\x69\xf9\x3e\xa0\x4b\x4d\xaf\xa8\x8c\xe0\x2c\xcb\x79\x28\x33\xab\x16\xcf\x27\x27\xed\x45\x0b\xb6\x3a\xc3\xa5\x21\xb3\x94\x1b\xd0\xc3\xf0\x1a\xf6\xf6\xb8\x71\x2a\xaa\x82\x0b\x8a\x49\xa0\x5c\xd5\x79\xb9\xb3\xbc\x6f\x01\xe6\xdd\x65\xfe\x7d\x70\x17\xc8\x4e\xf7\x8b\xcd\x45\x0f\x55\x57\x2b\x30\x43\x9e\x13\xff\x10\xaa\x00\x61\x43\xa9\x67\xfb\x98\x68\xd4\x08\x54\x14\xe8\x96\x56\x7c\xf9\x14\xcf\x9d\x8b\x30\x7b\x08\x3b\x49\xa2\x26\x5d\xdf\xaa\x2f\x95\x97\x13\x91\x83\x36\x0a\x69\x6f\xa9\x36\xf9\xb9\xf4\xc3\x1e\x35\xb1\x97\x11\x1a\x4c\x40\x67\x14\x76\x77\xe4\x1b\x5b\x3f\x0d\xb6\x0e\x29\xee\xed\xde\xe6\xb7\xc9\x9b\x16\xae\x71\x89\x3d\xee\xe7\x53\xe0\x65\xc4\xbb\x43\x59\x94\x21\xe7\x3d\x35\x14\x63\x4d\x14\xa3\xac\x99\x4f\xae\x09\xa8\x20\x17\x64\xc6\xaf\x85\xbd\x19\x99\xfc\xcb\x80\x13\xa8\x42\x4c\x92\x61\x52\x7a\xa6\x8a\x85\x9a\x5b\x96\xc7\xff\xe4\x47\xe8\x35\xf1\x5f\xec\x47\x60\x73\xec\x67\x8e\x52\x7c\x7e\x81\x03\xa8\xc2\x1e\x11\xee\x3c\x24\x9b\xa6\xfd\x74\xfd\x2c\xa1\x15\x8d\xb1\x4d\xdb\x99\x89\x68\xa6\xec\xe2\x82\xcb\x2e\xb0\x57\xc2\x0e\x94\xf4\x56\xe8\x73\x34\x55\x98\xd0\x7e\x09\x81\xdd\x7b\xfc\xd5\x96\x59\x3f\x00\x1f\x16\x36\xdf\xe0\xdb\x05\xc3\x88\x10\x53\xab\xab\xf7\x4c\x2b\x4e\xaf\xef\x97\x88\x78\x2c\xb5\x2a\x4a\x9a\xaf\xe7\x60\x9c\x60\xf6\x50\x3d\x2f\xe6\xf4\x7c\xf0\x40\x11\x6a\x2f\x17\x04\x31\xce\xe9\xc9\xab\x3b\x42\x27\x02\x23\x6f\xf7\x42\x48\xb5\xf4\x5c\x75\xf3\x64\xe9\xe6\xe3\x2c\x3d\x40\xe3\xea\x02\x26\x97\xfb\xa2\x27\x86\x04\x57\x22\x30\x90\x78\x6f\xa7\x8d\xc1\xd4\x62\x27\xaa\xca\x5f\x2c\xd8\x34\x6c\xfc\xc4\xa9\x14\x33\x80\x0c\xbf\x28\x1a\xd8\xcd\xd8\x5c\x4b\xc5\xb8\xa8\xa3\x3d\x66\xb0\x30\xaa\x71\x14\x72\x39\x7b\x33\xbc\xb2\x78\x09\xec\x93\x6f\xf4\x2b\x30\xe6\x19\xe4\x3f\x14\xa9\xa6\xb5\x88\xdb\x03\x76\x40\x85\x3d\x32\x9e\x4b\x71\x78\x33\x37\xb6\x4a\x3a\x78\x6f\xe1\x2a\x8f\xa5\x68\x23\x96\x37\x8a\x06\x24\x02\xf4\x58\x2e\xcb\xb8\x64\xd2\xb5\xab\x50\xb5\xe3\x99\x19\xa3\xba\xf7\x0a\x81\xc4\x1d\x4b\xbb\x4d\x4e\x0f\xf6\x85\x62\x89\x35\x13\xbd\xca\x5a\x43\x4f\x0d\x6b\x48\x81\xd4\x4b\x03\xa1\xd8\x4d\xa3\x5e\x52\x83\x78\x11\x98\x42\xd3\x21\x46\x31\x54\xca\x32\x27\x4b\x4e\x5f\x49\x65\xbe\x29\xb4\x52\xe5\x8a\x83\x51\xf6\xae\x92\x75\x48\x5c\x4f\xbe\x68\x68\xca\x93\x2e\xec\x22\x0a\x71\xfc\x3c\x8b\x8c\x20\xf0\xae\xe9\x28\x18\x91\x0a\xfc\x09\x7b\x3d\x48\x65\x1a\xa3\x00\x7e\x59\x08\x7f\x0b\xfa\xb4\x5a\xe8\x11\x46\x63\x13\xf0\x8c\x74\xec\x5a\xd6\x62\x1e\xba\x14\xbb\xa1\xdd\xf0\xb0\x7d\x56\x98\xda\x21\xe9\x08\x88\x72\xf7\xd4\xca\x14\x90\x96\xae\x52\x73\xb8\x0c\x0f\xa9\xde\x2e\xed\x25\xbe\x18\xf1\x3d\x31\xa0\x08\xb8\x66\x72\x73\x4d\xb9\x9a\xa2\x11\xd9\xe6\x39\x00\x83\x63\x14\x9b\xa2\xec\xd6\x0e\xcd\x9b\xc3\x99\x3b\x70\xc3\xc1\x77\xee\x20\x06\x75\x03\xc0\x30\x14\x6d\xa8\x6f\x9e\xbe\x58\xdc\x79\xd3\x32\x10\x27\x6c\xd5\xb1\x04\x5f\xe5\xab\x91\x68\xb3\xb2\x1a\xdd\xf7\xdc\x19\x8c\x9b\x37\x41\x29\x77\x46\xe5\xf9\x98\x7c\x88\x2d\xd0\x1b\x88\x5f\x12\xfa\x59\xd0\x84\xb0\xe7\xbd\xdc\x81\xdf\x39\x7b\x27\xc9\x7b\x33\x78\x19\x13\x36\xc0\xf0\xd2\x91\x0e\x84\x81\x9b\x5f\x9d\x85\xd7\xb5\x58\x7c\x08\x07\xc5\x86\xea\x79\x35\x14\x64\x32\x33\x01\xed\x1d\x7b\x9d\xd0\xdb\x4e\x55\x57\xb3\xe5\x88\xe9\x05\x1d\x50\x45\xa5\xe9\x87\x99\x56\x97\xbd\x75\x3e\xe7\x7f\xba\x4d\xff\xc5\x9e\x86\x97\x74\x3f\x7f\xbe\xf5\x01\x49\x27\x9e\xb7\x81\x9c\xe8\x89\x1b\x8c\x24\x64\x27\xa6\x75\x22\x1a\xfa\x88\x64\x37\xae\x28\x32\x23\xb7\xfa\x51\x35\x4c\x3e\x0c\xd0\xde\x4e\x9f\x4e\xc9\xbe\x07\xde\xc8\xfa\x77\xc1\x36\xee\x2b\x32\x0c\xb0\xb9\xd2\x81\x2f\x6b\xaf\xf3\x9c\x8a\xfc\x98\x9e\x58\x8b\xc1\xe5\xba\x26\x12\x2f\x8a\x3d\x40\xac\xe2\x93\xa3\xbb\xbe\xa0\x23\xe9\x48\x90\x10\x81\x00\x43\x35\xf8\x85\x61\xb4\xf4\xa8\x0d\x51\xf1\xa2\x70\xbb\x9e\x25\x3e\x23\x80\x18\xed\x88\xde\x8e\x01\x72\xde\x93\x98\xbe\x0f\x3d\xcb\x43\xd3\x77\x91\x49\x78\x7d\xf6\x75\x97\x50\xde\xde\x93\x91\x61\x7f\xca\xad\xc6\xca\xb2\x1e\x65\xfa\x17\xa4\xe9\xcd\x9d\x4b\x5e\xf1\xfb\x86\xdc\xd0\xa8\x24\x38\xf4\x8c\xd8\x1d\x8d\x39\xb3\x43\x97\xd5\xb9\x79\xf7\x14\x7d\x87\x6f\xf4\x13\x2a\x23\xd6\x40\xea\x57\x9a\xf7\x72\x15\xfa\x48\x09\x30\xa7\xbd\x5a\x9f\x54\x4a\x74\x14\x1d\x74\x47\x44\xd6\x68\x04\x61\x8d\xc6\x30\x6a\x85\x44\x50\xe1\x41\xa0\xba\x2d\x16\xb4\xc6\x4b\x05\x6b\x59\x6d\x40\xa6\xc6\x2b\xf5\xaf\x52\xc4\x80\xba\xd3\x7a\x0c\x02\x91\xa2\x54\x9b\x39\xeb\xb8\x6c\xf1\x34\x05\xba\xdd\x3f\xb0\x54\x2e\x69\xb4\x83\x29\x31\xcd\xd0\x18\xec\x40\x54\x90\x3b\x4a\x37\x5e\x02\x6a\x0b\x69\x5f\x59\x3c\x4d\xd2\xcf\x24\xe0\xcb\xbc\x74\x43\xdf\x74\x66\xa0\x6c\xeb\x16\xd0\x20\x83\x29\xa6\x8e\xd7\x04\xf4\x31\xe9\x53\x94\x46\x0c\xc4\xde\x9c\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\x3b\x91\x89\xb1\xbc\x81\x57\x0e\x0c\xb0\x4c\xb9\xba\x53\xb3\x1a\xaf\x2c\x3f\xdf\xaf\x93\x7c\x6e\xcb\x6b\x3b\xc3\x20\xd5\xc2\x63\xad\x0a\xcc\xd5\xd7\x6e\x8f\x08\x68\x94\x8e\x4a\xf5\x41\xb9\x4c\xfb\x6c\x72\xce\x92\x6c\xc1\xbe\x8b\x3d\xd9\xd0\x9a\xcf\x57\x51\x95\x09\x02\xbb\x90\xce\xcc\x8c\xdc\x39\x86\x95\x2b\x57\x02\x1e\x96\x93\x03\x62\x11\x9a\x33\x52\xc3\x39\xc4\xa0\x4e\xba\x72\xbc\x3d\xf2\x22\xad\xb1\x13\x0c\xbc\x3d\x9e\x17\x84\x3f\xf3\xe9\xf6\x4d\xdc\xfd\xc5\xec\xee\xf9\xc3\xee\x8a\x05\x92\x24\x88\x37\x26\x60\x4f\xb0\x01\x7e\x2e\x5e\xb3\x9f\x9f\xc9\x48\xe6\x9f\xb4\x11\x32\x86\xc0\x55\x60\xeb\x5c\x5a\x81\xb1\xa8\xb1\xc3\xe4\xcb\x35\xe5\x45\xac\x1b\x27\xa7\xbc\xed\x3d\xbe\x96\xb5\x5c\x4a\x33\x5f\x9e\x26\xac\x1e\xf9\xa7\x24\x79\x41\x6e\xd1\xa9\x2c\x56\x6a\x0e\xc6\x30\xd2\x93\x7b\xe4\x4a\x5c\x82\xdb\x99\x57\x15\x91\xaa\x2a\xbd\xd6\x80\x11\x1a\x18\xbb\x79\x2a\xba\xa6\x65\xa6\xeb\x9d\x2e\x33\x97\x82\xf5\x44\xc2\xd7\xfc\xdc\xdd\xf4\x52\x77\x1a\xed\x79\xef\x22\x38\xba\x36\x5d\x74\xea\xa6\x09\xc4\x8b\xd8\x7b\x5a\x06\xc0\x0c\x8b\xcc\x5b\xb7\x45\xe2\x2a\x7a\xc1\xe7\xbd\xd6\x3c\x2e\x8f\x27\xa7\xde\xf2\x97\xa9\x4b\xa9\xd6\x08\xb3\xab\x92\xdc\x5b\xb6\x1d\x22\x98\x2e\xfb\x34\x7a\xa2\x29\x41\x2f\xd5\xab\xa7\x63\x47\x7b\x5d\x52\x05\x5e\x60\x09\xcd\x63\x88\x01\xc7\x34\x99\xd3\xcb\xdc\x01\x6f\x45\xc1\xc2\x5e\x19\x69\x89\x4b\x69\x2a\xf6\xf7\xca\x9e\x2b\x7a\xce\xb8\xb0\xef\x42\x4d\x99\xd6\x4c\xcb\x48\xbd\xbc\x68\x71\x94\xda\x4e\x4d\x49\xba\x10\xdb\xfe\xa6\x6a\xb6\x6a\xaa\x85\xf2\xe2\xf7\x86\x58\x36\x69\x39\x94\x34\xd1\x4b\x17\x5a\x1e\x6e\xc1\xc3\x04\x5f\xe7\xc2\x7e\x00\xde\x29\x01\x99\xab\x14\x95\x8e\x2c\x97\xef\xbb\xdc\x3e\xa8\x17\x4d\xa6\x34\x3e\xbe\xac\xf3\xa2\x07\x5e\xf9\x26\x8a\x19\x00\xba\x58\xe1\xed\x7b\x30\xb6\xcc\x83\x9f\x6c\x41\x74\xdc\xf0\x4a\xd0\x93\x15\xa0\xf0\x09\x56\xd4\xfb\x85\xab\x86\x18\x19\xe5\x90\x30\x69\x55\xf1\x47\x95\xac\xbb\x96\x9c\xce\xc0\x93\x4f\x08\x00\xd1\x2b\x1d\x4e\xc4\x01\xe1\xf6\x54\xdf\x86\x08\xe6\x82\xa1\xa4\x35\x34\x61\x56\x0f\xcf\x3a\xb5\x27\xf0\x8e\xdd\x80\xca\xb6\x6e\xa0\xf4\x86\xcf\x55\xcb\x74\x1c\x09\xb6\x24\xf0\x16\xe7\xc5\x6d\x15\xe1\xca\x61\xb3\x6d\xb0\xe1\xdd\x66\x4e\x25\x15\x23\xa4\x32\x14\x31\x77\xf5\xa4\xfe\xe4\x30\x0d\x58\xec\xc3\xb0\x03\xf1\xd7\x65\x3f\xd3\xba\xe8\x8d\x09\x10\xd1\xe8\x78\xa1\x74\x0d\x45\x1f\x32\x27\x12\xa0\xd8\xf4\xa9\xb4\xe4\x70\x67\x80\x60\xd5\x12\x00\x52\x3e\xc7\x9a\x61\xd2\xc7\x0d\x21\xe4\x22\x86\xac\x2c\xeb\x30\x6f\x61\x24\xa1\x04\xfa\xbb\xd0\xd5\xf9\x15\x28\x85\x94\xe6\x69\x1b\x00\x52\xbc\x18\x62\x91\x51\xff\xd4\x27\xb5\x35\xdd\x5f\xec\xe7\x97\xa3\xf3\x4f\xbb\x6b\xdb\x81\x86\x78\x7b\x7a\xef\x6f\x8f\x22\x0e\xdf\x77\x41\x76\x38\x08\xe6\xdf\xbe\x65\xf2\x8a\x0f\xdf\x8b\xd3\x9e\x51\x5b\x25\x32\x02\x6b\x6c\xdf\xd6\x72\xcb\x51\x82\x7f\x9c\x79\xa3\xe0\x33\xbf\x10\xca\xcc\xb7\x9c\x4e\x78\xc6\xaf\xcb\xeb\x59\x10\x10\x51\x22\x0f\xf9\x56\xe5\xec\x1e\xab\x6e\xe5\x32\x00\x2d\x41\x61\xe3\xc2\xf6\x51\x64\xd4\xd1\x82\xf8\x89\xc9\x3c\x50\xf9\xb4\x80\x80\xf9\xbe\xdc\x12\x58\x6b\x6f\xba\x0e\x83\x0d\x8c\x61\x8b\x81\xf0\xf4\xb4\xf0\x34\xbb\xc7\xfb\xe5\x3a\x42\x88\x88\x5e\x05\x83\x0e\x0a\x1a\x60\xdd\x4e\xf2\x43\x1f\x94\x99\xcb\x7b\x22\xa4\x61\xe4\x8c\x57\x79\x72\xa0\x06\xf1\x27\xf9\x7a\x19\x66\xda\x1e\xee\x06\x7b\x7f\x55\x34\x92\xa0\x79\x31\x5b\xc0\x62\xd2\xf2\x70\x69\x3a\x22\x69\xac\x13\x9f\xde\xa4\xd3\x9b\xbd\x1b\xf4\x9d\x79\x31\x81\x6c\x18\x9c\x6c\x45\x06\xcd\x4f\x31\x99\x54\x0c\xad\xa5\x7b\xd8\x86\xd9\x41\x53\x8b\x22\xb5\x5e\x4c\xf5\x66\x27\x81\x21\xab\xfe\x91\x34\x67\xc6\x1d\xf9\x17\x6d\x46\x6d\x2b\x5f\xe9\x33\x2f\xbe\xab\x40\x7c\x3f\x5e\x32\xb4\x0c\x5a\x51\x9f\x50\xa6\x9b\x27\xb9\x84\x1d\xfb\x69\x4e\xd5\x03\x73\xf7\x13\x81\xbc\x28\x9a\x0f\x6e\x6f\x13\xd0\x38\x88\x3f\x97\xbd\xf4\xb4\x90\x9c\x3a\x1b\x39\xbd\x0f\xf6\x99\xf5\x22\x4f\xe3\xf9\x71\x6d\x95\xb7\x19\xb8\x79\xa7\x5f\xd9\x4b\x99\xf1\xb7\x1a\xd3\x08\xac\x55\xa1\x57\x9e\x56\xa5\xb6\x8f\x19\xa4\xdf\xef\x8d\xa0\xc1\x5c\xf4\xda\x85\xbc\xe7\x49\x6d\xde\x2e\xa2\x82\xea\x34\x08\xe6\xdd\xb5\xed\x71\xaf\x36\xdc\x06\xbc\x3e\xd4\x2b\x7d\x7e\xdd\x55\x6e\x02\xde\x33\x73\x8e\x02\x67\xb1\x34\xeb\x84\xde\x5d\xd0\xd8\xbf\x0b\xe9\x8e\xbd\xdb\x87\x99\xe7\x31\x31\xcf\x1a\xd1\x37\x9e\x85\xdc\x6a\x30\x49\x79\x50\xcb\x2f\x26\xad\x51\xa1\x01\x42\x04\x07\x29\xef\x9c\x60\x95\x52\x87\x79\xee\x8d\x98\x77\x82\x05\xf2\x6e\x71\xe0\xf0\xee\xd1\x40\x9e\x2a\x5c\x60\xe6\xd3\xbd\x4e\x85\xcc\x62\x9b\xe6\x04\x4f\x8e\xce\xba\x4c\x39\xca\x11\x4d\x8f\x8c\x07\xb5\x3d\x8d\x77\xc9\x7e\x53\xcc\x3f\x33\x66\xec\xfe\x62\x31\xe3\xfd\xf6\xeb\x9f\xfc\x7f\xf3\x10\x6f\xeb\x16\xb9\x54\x41\x78\x8e\x39\x99\x81\xd3\x92\x1f\x7d\x8a\x9f\xce\x7e\xce\xd8\xbc\xf1\x74\x60\xec\x95\x76\x8c\x77\x4f\xc3\x27\xdf\x79\x7d\xff\x90\xef\x7b\xfa\xce\xcb\x66\x1c\x5f\xe2\x8b\x78\x62\xcb\xd0\x77\xd8\x61\x96\xdd\x20\x7f\x5c\xe1\x2a\x7b\x3c\xb3\x82\xb0\x62\xe2\xff\x67\xef\xbf\x75\x35\x46\x9a\x2d\x41\xf4\x81\x68\x50\x2b\x93\x5a\x6b\x4d\x8f\x5a\xab\x8f\x9a\x4f\x7f\x51\x7f\x9d\x7b\xaa\x1a\x98\xc1\xe9\xc1\xd4\x00\x65\xb4\x41\x63\x6f\xf0\x5b\x4c\x64\x66\x44\xac\x08\xae\x48\x1a\x15\x49\xa4\x96\xb9\x42\xc2\xde\xb1\x49\x94\x5b\x57\x5d\x51\x14\x40\xd0\xad\x6c\x59\x8c\x40\xd7\xe8\xe7\x87\x33\xaf\x99\xf2\xd5\x8e\x7b\xbd\xd9\x37\xf8\x33\xa0\xe5\x7a\xa3\xdd\x15\xcb\x58\x15\x56\x5e\x79\xdd\xd9\x1b\xc3\x0f\xd2\xbc\x61\xba\xb2\x3c\x53\xab\xd8\x53\x59\xa1\x6d\x18\xf5\xf3\x79\xf3\xcd\xa7\x23\x98\x3d\xdc\x9e\x1a\x70\xfc\x99\x10\x29\xe3\xa6\x01\xd6\x30\x2a\x2e\x46\xb3\xc6\xbc\x77\xb6\x9d\xd2\x69\xa8\xd3\x11\x7a\x70\x36\x31\x29\x32\x79\x66\xdb\xbb\xba\xd5\x8a\x2c\x6b\x9c\x77\x6c\xee\x1e\x87\xa2\xed\x9c\x69\xc3\xd3\x2c\xfb\xf4\xdd\xe0\x75\xee\x86\xc1\x0c\x33\x34\x9c\xc3\x7e\x61\x0d\x01\x6c\x24\xb0\x31\x29\xb1\x13\xf4\x34\xb2\x1c\x6c\x03\x1c\xe4\xec\x29\x14\xca\x5b\x7e\x2f\x97\x8e\x96\x42\x27\x82\x74\xf2\xcf\x5d\x9e\x1c\xd7\x1d\x1e\x1a\xb7\xe8\xd5\x71\x29\xd6\xff\x8a\x0d\xb3\x55\x82\xd7\xe5\x92\x20\x8f\xfe\x38\x19\x26\xee\x72\x1c\x2b\x39\x3b\x14\x6a\x07\x8f\x95\xa2\x1b\x40\x08\x44\x3a\xbe\xb2\x92\x0f\x2d\x2a\xee\xf9\x75\xbb\xd1\xd1\x10\xf6\x42\x71\x67\x38\x62\x3d\xb0\xe4\xd8\x10\x8f\x28\xdf\xe2\x23\x6c\x81\x11\x42\xd9\x1c\x98\xac\x1e\x69\x13\xf5\x94\x68\x87\x7d\x6c\x64\x7d\x13\xe3\x3d\x50\xb0\x77\x11\x85\xc2\x13\x83\xd3\x71\x3f\x01\x2d\x29\x73\xd6\xdb\x94\x67\x2c\x6f\x6a\x76\x7c\x0c\x69\x2f\xd5\x4b\x3b\x73\xdc\xfb\xe7\x12\xf2\x60\x0f\xee\x6e\x31\xf1\x56\xa4\x37\xdb\xac\x73\x38\x83\xdc\xb7\xe7\x03\xf6\x4c\xf9\x04\x42\x8f\xd9\x1f\xc6\x82\xd0\x70\x7e\x9f\x74\xcc\x90\x57\xf1\xa2\x13\x02\x34\x7e\x16\xb8\x30\x76\xb4\xbf\x81\x66\xe3\x6c\xcf\xcb\xce\xea\xbd\x0a\x9d\x27\x7b\xbd\xdf\x1d\x7a\xbc\x0e\x94\xd7\x9c\x2f\xd1\x5c\x71\x38\xa2\x7c\xc0\x0d\x4d\x73\x37\x07\x7b\x8a\x15\x3a\xd4\x5e\xf0\xc2\x57\x57\x59\xa1\x39\xd6\xe4\x85\x0c\x00\xa4\x97\x67\x4d\xfa\x3f\xa7\x8e\xde\x35\x3f\x72\x61\xe0\x64\x26\xf3\x0f\xc7\xb2\x7f\x19\x87\x2c\xc5\xbf\xec\x90\xa2\x7f\x10\xc2\x24\xf5\xaa\x42\x5d\x38\x91\xc2\xd6\x86\xd6\x73\x93\x25\xcf\x0a\xe5\xda\x71\x02\xec\x2e\x42\xea\x96\xe5\x15\x34\xb9\x52\x3d\xa0\xbb\x93\x55\xd5\xae\xeb\x2b\x62\xba\xf5\x39\x27\x66\x3c\x77\xb2\x42\x72\xe3\xb5\xca\x79\xdf\x41\xe8\x71\xe1\x31\x42\x3b\x8c\x66\xf5\x08\x78\xdf\x57\xac\x6f\x9a\x4c\xaf\x48\x62\x95\x89\x53\x28\xb8\x03\xb6\x05\xd8\x9e\xa0\x28\x95\x9a\x96\xbf\xc3\x09\x15\x98\xe6\x9a\x69\x00\xed\x16\xa5\xf3\x75\x1c\xe3\x8d\x42\x1a\x72\x6f\xf4\x27\x2c\x5e\xcd\x4c\x57\xe5\xa1\x82\x1e\x3f\xf1\xcf\xeb\x0b\x5a\x5a\x2e\x2a\xed\x5a\xce\xe5\x28\x1e\x20\xad\x19\x53\x8b\xaf\xba\xa4\xca\x97\x3c\x41\xe1\xb0\xe2\xd0\xd4\x83\x85\x79\xdf\x8e\x3b\xb8\xe3\x38\x61\x50\x26\x58\x10\x47\x0e\x11\x26\xa8\xbb\x8f\xa8\xee\xe6\x78\x50\xbe\xbe\xb3\xa0\x7e\xec\x0f\x9e\xc3\xfd\xa3\x1e\x25\x45\x0a\x1c\x83\x05\xa6\xba\xcf\xc0\xc5\xbe\x10\xf7\xa1\x0d\xa3\x5f\x8d\x52\x7d\xac\xf8\x8d\xfd\x7b\x28\x6e\x65\xa8\xee\x7a\x73\x60\xe7\x70\x4c\x16\xa5\xf0\xaf\x50\x60\x4c\xfc\x1d\x4e\xf5\xec\x5e\x4e\x78\xee\xbb\xa7\x98\x98\xd7\x80\x48\x54\xf2\xcd\xf8\x05\xdd\xa8\x92\xc9\x4c\x78\xc7\xf9\x3a\x3e\x83\x3a\x17\xba\x12\xc3\x9b\x4b\x95\x49\x8b\xbc\xbd\x59\xdc\xe3\xcd\xe6\x8c\xbe\xc5\x2f\x57\x71\x9b\x03\xce\xf4\xc4\x1d\x6f\x21\x55\x71\x0b\x29\xf0\xad\xb1\xcc\x82\xbc\x46\x40\x99\x72\x64\x13\x48\x34\xc5\xa3\x4d\xb5\x90\xd7\x90\x43\x70\x4b\x17\xcc\x65\x97\x07\x49\x58\xd2\x0b\x3f\xf3\x11\x94\x68\xde\x07\x0f\x33\xa0\xc0\x88\xec\xb2\x0a\x8a\xcd\xf1\xf3\x21\x23\x50\xcd\x9a\xf7\x26\x28\xef\x1d\x90\x44\xe4\xef\x79\x16\xc0\xd4\x80\x16\x65\xc9\xd8\x35\x2d\x2c\xf8\xdd\xef\xe4\x1c\x86\x32\x94\x3e\x1b\x40\x13\xb0\xb3\x56\xf6\xea\xfb\x4c\x69\x19\x49\x4d\x0e\xdf\x3f\x60\x45\x91\x72\x6c\x0f\x39\x0c\x04\x7b\x6d\xa3\x24\xc0\x4c\x29\x5c\xdb\xe0\x7e\x0e\x33\x9b\x13\x73\x55\x87\x4e\xdc\x8f\x10\xe1\x3f\xc6\xa8\xd6\x91\x66\x46\x3f\x40\xbb\x28\x3f\x61\x98\x21\x38\xab\xea\x51\x45\x8c\xfc\x87\x6b\x22\xeb\xbf\xad\xce\x39\xb5\x7f\xd5\x39\xa1\xff\xd4\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\x8d\xbb\x6b\xfb\x2f\xcb\x21\x5b\xf3\xaf\x1c\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\xac\x79\x58\xe7\x7f\x99\xe6\x61\x3a\xfe\xd2\x3c\xd0\x87\xf5\x47\xbe\x1a\xc7\xf6\x0a\x71\x4c\x10\x4d\x6a\xce\x41\xd8\xc3\x32\xa6\xe9\x8b\xc0\xa0\xb5\x12\x55\x2b\x3c\x91\x6d\x3a\xd8\xd8\x42\x4f\x0b\xd0\xa8\xd4\x04\xdf\xa3\x90\xac\x43\xe8\xfd\x38\x47\xa8\x70\x90\xa3\xfd\xa2\xc7\x94\x60\x7e\xa0\x53\xc4\xea\xe1\xef\x99\xe1\x09\x5a\x94\xd4\x9f\x95\x37\xa5\xc0\xaa\x02\x10\x18\xfe\x70\x79\x9f\xa0\x3c\x69\x10\xba\xd6\xa5\xf5\x89\x14\x35\x62\x13\xc9\xc3\x15\x86\x9a\x0b\xad\xf5\xe9\xe8\xaa\xb1\x64\x5b\x7f\xc7\x09\xdc\xe8\x46\xe1\x31\x59\xd3\xce\xb3\x57\x3c\xb8\x4e\xa9\x91\xee\x8f\x49\xd7\x73\x81\xab\xe6\x0d\x31\x9c\x24\x5d\xc4\x61\x7b\xd7\x7b\x09\xbc\x26\x2c\x51\x8a\x27\x94\x25\xcb\x56\xae\xad\x67\x71\x63\x2c\x74\xa0\x59\x33\x8f\x18\xa7\xda\x3b\x92\x0c\x4e\x78\x62\x3b\x01\x5b\x6e\xc6\x6e\x86\x5a\x50\x1c\xcf\x76\x8a\xdb\xb6\xa1\x41\xe7\x71\x52\x86\x5b\xc2\x14\x32\x65\xa0\x66\xe3\x41\x87\xe3\xec\x62\x51\x97\x9a\x2c\xe4\xd7\xf8\x23\xa2\x37\x73\xc1\x90\x38\x6d\xcd\x7e\x49\x16\xe3\x7d\x72\x0c\x36\xcc\x08\xba\xd5\x18\x55\xc4\xb0\xf9\x40\x3b\xc2\x5a\x4b\x91\x79\x06\x71\x76\x31\xf3\xc1\x32\x9f\xb8\xca\x29\x3d\x89\x2b\x90\xa1\x19\x55\x37\x23\xee\x69\xca\x36\x55\xb3\x86\x57\x68\x3e\x6d\xe8\x4d\x19\x84\xf7\x70\xbd\xa1\xdc\x7c\x4f\x74\x0e\x49\xd1\xbd\xbc\x29\x28\x3d\xec\x0c\xe0\x28\xa0\xd7\xae\xcf\xe1\x53\x5e\x4b\x45\x71\x7a\xa0\x13\x17\xaa\x9c\x92\x45\xb4\x89\xcd\xd7\x3b\x5e\x0c\x94\x5f\x4a\xd8\x1b\x78\x60\x2f\x56\x21\x5b\x39\x05\xe7\xcb\x75\x57\x5b\x45\x2d\xfa\xac\x77\xd2\xac\x29\x7a\x05\xc0\x17\xbd\xc2\xc2\xa1\x72\xe6\xb7\x4b\x9b\x52\x91\x91\x98\x60\x55\xb2\xf4\x36\x47\xaf\x7f\x4d\xd3\xdf\x10\xe3\xdc\x36\x00\x4a\x55\xc3\x29\xf2\xba\x9a\x8b\xc8\x34\x82\x61\xc1\x6e\xaa\x2d\x24\xeb\x34\x6e\x87\xbe\x26\x84\x17\xf3\x5d\x32\x10\xeb\x18\x4c\x23\xa2\x1c\xb1\xce\xf9\x69\x36\x34\x62\xd0\x8c\xe8\xc3\x65\xe7\x71\x2d\x31\xe4\x80\x28\x5d\x0b\x62\x3c\x33\xcb\xd2\x4b\x91\x3e\x2b\x66\xcc\x3b\x5c\x94\x15\x02\xa3\x2c\x05\x57\xe4\x73\x33\xc5\x88\xf5\x43\x96\x41\x4a\xe0\xf5\x41\xa9\xab\xf7\xa0\x43\x42\x4f\x84\xde\xc5\xfc\xb8\x83\x1c\x29\xb8\x1b\x4e\x42\xfa\x69\x73\x22\x04\x14\x1d\xaa\xa3\xa7\xba\x93\x0b\xf1\xd9\x03\xd4\x0a\xbd\x9f\xc9\xe3\x2d\x98\x3c\x46\xca\x4d\x18\xa8\xc8\x8e\x33\x4f\x27\x6d\x17\x67\xf9\x6b\xed\x56\xa5\x6c\x12\xe9\x7f\x7c\xa5\x24\x0b\x21\xf0\xd2\x0a\xa4\x76\x8e\x0c\x9a\xb6\xc9\x54\x0b\x4c\xc3\xd3\x29\x38\xc8\xc3\x20\x4c\xab\x68\x7e\x27\xf6\x65\x47\xf1\x86\xec\xc3\xd0\xa9\xe1\x53\xed\xdb\x01\xc5\x5f\xd3\xae\x9a\x41\xcd\x6e\x18\x22\xfa\x85\x6c\x74\xa5\x2b\x97\x57\x33\x8c\xc1\x64\x59\x31\x8f\x63\x21\xb2\x53\xf2\xcf\xc6\xf4\xf5\x5f\x96\x4b\x0f\xed\xdf\x3f\x0f\xf8\x9f\x98\x6e\xfb\x06\xf9\x7a\xe9\x3a\x7d\x3e\xcd\x9b\xd9\x14\x31\x87\x58\x7b\x1d\xd7\x35\x3f\x80\x79\x44\xfa\xd3\x8e\x0b\x6c\xaf\x1a\x64\x86\x0e\x10\x85\x8e\x58\x2e\x4c\x39\x22\xd9\x96\xba\xbb\x63\x03\x6d\x09\xb6\xcd\x0f\x54\x65\x9a\x5c\xd4\x20\x8d\x0f\x3d\xa0\xc1\xac\xe0\x09\xd3\x95\xbb\x00\x08\x1c\xa7\xf1\x6f\x7c\xc6\x5e\x50\xbf\xd2\xc5\xcf\x1a\x9f\xf5\x69\xbf\xd2\x87\x68\xbc\xeb\x28\xe9\x88\xce\xfb\x56\x24\xfb\x06\x2f\x65\x7a\x76\x0b\xf0\xde\xa8\x24\xce\x7c\x4f\x5d\x8f\x1c\x7a\x86\xf1\x21\x95\x74\xd1\x02\xe1\x83\x3f\x15\xe1\x83\x80\xa0\x41\x94\xbc\xc4\xe4\xc7\x3f\x55\xa3\xd2\x01\x34\x72\x00\xb3\x28\x4a\x28\x35\x34\xa7\x03\x97\x62\xe5\x36\x46\x69\xbc\x33\x93\x0f\xb4\x47\x5d\x38\xab\xbf\x59\xe0\x1b\x52\x93\x06\xa0\x03\x99\x02\xeb\x02\x03\x74\x49\x76\x9f\x7e\x9e\xf7\x1c\xb1\x51\x67\x68\x4c\x56\x23\x05\x68\x7d\x8d\x6a\x75\xa0\x02\x9d\xab\x3a\x37\x76\x43\x7e\x41\xb1\xee\x1b\x49\x2e\x93\x26\xe8\x8f\x75\xc1\x70\xe4\x80\x58\xe0\x91\xec\xe5\xdb\xf4\x8d\x47\x08\x05\x5a\x93\x41\xfd\xc7\x74\xf6\x76\x94\x74\x66\x16\x30\xec\xe3\x14\x1d\x6e\x96\x38\xbd\x3b\xc3\xbc\x58\xb8\x23\xbe\x9c\x83\xb4\x93\xd9\x1f\x53\xf1\xa3\xbb\x31\x8d\xc4\xae\xf4\x50\xed\x44\xc1\xa2\x99\x5f\x2f\x33\xdd\xf5\x63\x7a\xf3\x63\x7f\x58\x8d\x5d\xb7\xd2\x94\x12\x8f\x25\x01\xc3\xed\x29\x27\x50\xcc\x91\x48\x91\x8f\xf7\xdc\x2e\x39\x37\x7e\x0b\x89\xfa\xd9\xe0\xda\xe3\xee\x9d\xf8\x0c\x9c\x43\x64\xe5\x4c\x75\x4a\xd9\xd0\xde\x94\x99\x81\x88\x63\x72\x47\x83\xd1\x18\xeb\x48\x98\x0e\x63\xa1\xa8\xa4\x19\xd0\xbd\x3b\x51\x3d\x0e\x2d\x7c\x6e\x52\x38\x85\x51\x3e\xee\x1d\x3f\x38\xef\xf6\xdc\x75\xd6\xa0\xb8\xb7\x15\xc3\x91\x09\x91\x1f\xf8\x72\x62\x3e\x58\x27\x05\x20\x87\xd0\x00\x7b\xc5\x98\xbe\x9e\x20\x47\x7e\x49\x23\xf6\x55\xe3\x25\x04\x1a\xbd\xde\x2e\xbf\xf1\xbd\x26\x72\x00\x41\x5d\x75\x42\x39\x63\x9d\x6a\xce\xfa\xcc\x8f\x1d\xba\x58\xeb\x32\x66\xf2\xbf\xe2\x72\xd5\x20\xa4\x05\xea\x67\x35\x1b\x7b\x6f\x63\x42\x31\xde\x0e\x32\x59\x99\xbb\x7a\x4e\x71\x5f\xe5\xf7\x21\x37\x6e\xf5\x41\x88\x25\x0b\x93\x87\x4e\xbe\x15\x97\x8b\x2e\x9b\x2c\xfa\x8f\xb8\x5c\xd0\xee\x3c\x61\xc4\xd9\x54\xcd\x58\x1e\x02\x5d\x64\x1e\xac\x74\xab\x1d\xa4\xde\xb5\x03\x80\x3c\xc1\x01\x24\xdd\x53\x84\xe0\x52\x27\x80\xe8\xf3\xac\x45\x80\xd5\x43\xb2\x65\x06\xb0\x06\xcc\xea\x12\xf3\x12\x35\x3c\x19\xf2\xba\xe2\x92\x03\x15\xd9\x39\xbc\xc5\x9f\x35\xe0\xad\x19\x46\x11\x32\xa5\x84\x27\xe0\x3a\xcb\x7f\xf2\x1d\xec\xba\x97\xff\x2e\x9b\xdf\xfe\xae\x85\x84\x0d\x01\x12\x92\x3a\x3f\x4a\x4d\x8b\xa4\x63\x51\x0e\x37\x6a\x54\x99\x59\x39\x56\x40\x14\x28\x39\x97\xce\xcb\xb2\x8a\x57\x2b\x4b\x6d\x31\x38\x31\x51\xbf\xf6\xbb\xa7\x70\x6f\xa3\x16\x06\xaa\xe2\x55\x89\x01\x84\x06\x4a\x7c\xdf\x75\x8d\x06\x42\x34\x4d\x5c\x16\x8e\xcd\xfd\x71\x50\x75\x8f\xac\x49\x1b\x38\x51\x8d\x8e\x17\xaa\x8b\x7c\x34\x9d\x71\x7c\x87\x49\x14\x3c\x25\x03\x82\xfc\x70\xbc\xd3\xfa\x53\xbf\x83\xa7\x91\x4e\xb3\xf0\xe5\xbc\x1c\xc9\xb1\xe5\xc2\xe1\x4d\x94\x82\xae\x91\xb7\x7f\x04\x5e\x97\x7a\x8f\x59\x19\x06\x77\xf4\x2e\x1e\xc0\x7b\x34\x26\xb9\x90\xf7\x22\x59\xbf\xad\xb9\xae\x55\x67\x33\x91\xba\xa2\x1e\x36\x03\xe6\x96\xfc\xd0\x74\x0d\x74\xaa\xf1\x2b\x00\xbf\x2c\x00\xe2\xd7\x73\x4e\x7f\x53\xc4\xf8\xa3\xdb\x67\x92\xf4\x61\xf1\xc8\x1f\x90\x3c\x57\x38\xff\x3e\xe9\x1b\x9b\xd8\xe6\xad\x2f\x48\x6d\x1f\x9b\x50\xfe\x00\xb5\x51\x39\x65\x7a\x09\xfa\x38\x11\xe4\x34\x05\x6f\xab\x91\x9c\xb4\xc3\xfc\xb4\x90\x14\xbc\xd5\x73\x40\xb4\x00\xc0\xf7\x2c\x4f\x2b\xf4\xa3\x30\x18\xa8\x54\x20\xc1\xfe\xad\x18\x20\x1f\x73\x2d\xe1\xfb\xd0\x05\x55\xc1\x4b\xb7\x23\x20\x46\xcf\xdc\x9d\x14\x8d\x62\x68\xf2\x1f\x70\x28\x2f\xb7\x0c\x6a\x6b\x6b\x89\x17\x93\x52\xf9\x21\x0a\x04\xb7\x96\x5a\xce\x09\xfd\x53\x41\x32\xb8\x6d\xc9\x17\xba\xad\x3f\xf2\x49\x3d\x6e\xcc\x48\x1e\x92\xf2\x40\x2c\xca\xd0\x16\x0f\x16\x2b\xb9\xed\x52\xb1\x56\x24\xee\xc0\x03\xa6\x7e\xa3\xd8\x14\xfc\x4d\x2c\xc0\x5b\x76\x51\xe8\xde\x16\x3b\x73\xab\x0e\x2d\x16\x63\x4c\xa6\xd0\xea\xa9\xd2\x78\xd5\xf2\xdc\x92\x17\x15\x82\xbb\xcc\xa0\x41\xf3\x0b\x3b\xcc\xbe\x52\x9a\x8e\xc9\x18\xb3\x85\xd9\x4a\x28\xad\x8a\x18\x17\xf7\x5c\x8e\x0c\x62\x1d\x52\x81\x19\xcc\x33\x8d\x08\xb9\x62\x8c\x72\x8e\x91\xa7\x64\xb4\x13\x66\x65\x97\x78\x8b\xfa\xb4\x1b\xab\x76\x97\xd6\xb4\x78\x56\xa2\x03\xdd\x64\x37\xa1\x96\x23\x9f\x6d\x1b\xb9\xe1\xb7\x62\x26\x98\x88\x20\x72\xa6\xcb\x1e\x9f\x3a\x03\x1b\x91\x88\x45\x17\x6c\x22\x0a\x57\xc7\x2a\x81\xeb\xc8\x64\x46\x1a\x26\x74\xf2\xdd\x1e\x44\x30\x92\xa6\x45\x26\x8d\x53\xb9\x61\xfc\xcd\x6d\x95\xbf\xc0\x9f\x79\xa4\x67\x44\xb6\xc1\x26\x29\x37\x69\x98\x9b\x17\x78\x88\x32\x99\xbb\x26\xac\x5e\x29\xdc\x07\x3e\x4a\x6d\xed\x94\xcc\xe0\xb0\xc2\x72\xe6\xa8\x69\xfe\x78\xb5\x66\x94\x8a\x3d\xdd\x5f\xf1\x4b\xf0\x47\x72\x10\x57\x54\x99\x7e\x84\x20\x85\xb2\xb9\x62\x50\x03\x8e\xa5\x37\x38\x70\xd9\x79\x40\xa9\x58\x50\x85\x73\xc0\xe0\x63\x92\xee\x94\xa9\x09\x62\x87\x43\xab\x45\x86\x6a\xbb\x97\x60\x4e\x56\xf1\x91\x65\xac\xd3\x94\xee\x19\x4c\x54\xfe\x42\x47\xb3\xd1\xce\x71\x41\x5c\xe2\x35\xe3\x4c\x26\x01\x6d\x81\xfa\x41\x0d\x79\x6b\xe1\xdd\xc8\xea\xef\x90\xf5\xb3\xe3\x1a\x48\x64\x06\xe8\x14\x4b\x7d\x2b\x56\x29\xc1\x1d\x21\xce\x7d\x0e\xec\xc9\x49\xc9\xc2\xbe\x80\x29\xfe\x39\xeb\xe0\x60\x55\xf0\x2a\x9a\x66\x07\xd0\xae\x0f\x3f\x10\xf2\x12\x86\xdd\x55\xd9\x0e\x8e\x13\xb4\x92\xfb\x1f\xce\x49\xfe\x6d\x5f\x23\x0e\xff\x72\x3d\xc3\x71\x09\xd3\x1f\x74\xc3\xfe\xfc\x40\x9c\x1a\x55\x43\x82\x2d\x76\x44\x09\x5d\x19\xc2\x62\xf5\x9f\xf3\x64\x93\x5a\x64\xc9\x7d\x9e\x28\xbf\x42\x23\xdd\xc5\xfa\x15\x1e\xee\xc9\xaf\xcd\x81\xaa\x4a\x92\xf9\xa1\x97\x3d\x87\x2b\xef\xea\x86\x3c\x82\xca\xca\x4d\x3c\x75\x75\x95\x1b\xad\xc0\xc5\x9f\x96\x4e\x15\x50\x55\x7f\x50\x0e\x98\x68\x11\x00\xe1\x66\xa4\xc8\x91\xf0\x7e\xe5\x11\x46\x40\xf0\xb2\x11\xf0\xb3\x9c\x4c\xc4\x4e\x9e\x94\x22\x93\xa0\x2b\x50\x5f\x9a\xda\x9c\xc8\x21\xd8\x6d\x56\xcc\xe2\xe4\x96\x8d\x4a\x83\xac\x71\x75\x04\x95\x59\x65\xd5\x3f\xdf\xe1\xd3\x68\xaa\x14\x68\xca\x82\x72\xdd\x00\x03\xb3\xf9\x61\x17\x8a\xf0\x3d\x5c\xdf\x9e\xe3\x1e\x74\xe9\xed\xf5\x94\x16\x46\x06\xfd\x94\x8b\xb6\xf8\x6c\x4b\x7e\x76\xf8\x9c\xf6\xac\xc3\xdc\x09\x67\x42\xae\x9e\x64\x7d\x29\x69\xa0\x2c\x58\xbe\x55\x61\xe2\x7e\xc5\x7b\x81\x54\x81\x7a\x76\xb2\xde\x02\x77\x80\xe5\x74\x62\x96\x89\x0a\x25\xe6\xbf\x93\x02\xb4\x4e\x01\xa7\xdb\x22\x00\x22\x70\x3a\x3a\xbf\xcf\xf2\x78\x0f\x9a\xb1\x17\xaa\xdf\x8c\x58\xa5\x5a\x1d\x5d\x3f\xa9\x5e\xd9\x66\x2b\x3d\x44\xea\xb8\xae\xb8\xc9\x58\xd8\xa7\x99\xe4\x5d\x50\x42\x14\x4e\xa1\xea\xeb\x2f\x83\xd2\xe6\x54\xa2\xaa\xd9\xf8\xee\x26\xc7\x84\x65\xd3\x90\x78\x3a\x69\xa0\x79\x87\xd7\x3f\x0d\xcf\x85\x57\xc4\xe4\x8e\x0e\x75\x63\x5f\x12\x85\x54\x09\x61\xc7\xed\xbe\x92\xfb\xd9\x1a\xf1\x33\xdf\xe4\x2c\x53\x25\x56\x18\xbe\xfc\x59\x47\x87\xd1\x94\x86\x9f\x58\xb9\x1a\x78\xbf\x51\x80\x4d\xd3\x36\x4d\xbf\x4c\x66\x6d\x26\xa1\x79\xb7\x53\xdf\x61\x6e\x11\x67\x24\xc1\x0a\xa5\xd2\xd5\x75\xe8\x17\x4e\x1f\xa2\x39\xf0\x14\x11\x55\x1f\xc5\x53\x82\x9d\xeb\x99\xe5\x69\x23\x53\xd5\x59\x45\xdd\xd1\xa4\x8a\x7b\x10\xa2\x96\x24\x1d\x2c\x2d\x21\x70\x79\x1c\x05\x30\x1f\x8c\x29\xc1\x21\x2c\x09\x4a\x0c\x92\x83\x0d\x51\x3d\xef\x8d\x88\x2e\xb4\x27\xbd\x8b\x05\x30\x35\x12\x87\x0b\x80\x36\xd6\xd0\x16\x3e\x96\xad\x34\x4d\x68\x17\xac\xfc\xd5\x8e\xed\xe0\x1d\x62\x88\xf9\xbb\xc8\x4a\xde\x43\x7c\xf6\xf7\xae\xd8\x1c\x23\xf2\x13\xf7\xbb\xaa\x11\x39\x3f\xa7\x0a\x93\x56\x13\xe1\xaf\x78\x62\x18\x53\x57\xcc\xb8\xc5\x61\xe3\x77\x98\xd1\x71\xb1\x74\xd1\x00\xad\xc3\xb0\x47\xd4\x6b\x3a\xd2\xcb\xa0\x8f\x4a\x0d\x5b\x24\x7c\x2c\x08\xc4\x54\xf0\x06\xe1\x8d\x99\xca\x48\x46\x34\x74\x97\xce\x72\x38\x96\x36\x73\x97\x66\xbc\xec\x29\xd8\xcf\xf4\xb6\x99\x04\x0f\xf8\x6a\x06\x49\xb5\xef\x34\xae\x6b\xaf\xe2\xfa\x01\xe9\x82\xe8\xa3\x81\xd9\xf3\x1d\x93\xaa\x88\xaa\xa6\x04\x89\xe1\xc6\xa0\x03\xb7\xa5\xb3\x0a\xf4\x1f\x76\x03\xdb\xbf\x2c\xeb\x98\xff\xe6\x06\xa8\xe3\x84\x20\x26\xb0\x03\x7c\x5f\x31\xd8\x1c\x3e\xf7\x59\x6b\x2f\xdd\x3a\x28\x54\x14\x67\x13\x04\x35\x48\x93\x58\xe0\xae\xfc\xe6\xa2\x27\xd9\x4f\x96\x07\x18\x36\x10\x7f\xfc\x8f\x9b\x23\xd6\x11\xd4\x52\x89\xba\x86\xf5\x7e\xc4\xba\xb9\x2a\x5c\xe5\xed\xf3\x13\x68\x83\xcc\xd2\xc9\xfb\x39\xd8\x82\x43\x78\x2d\x1b\x73\x6c\xdb\x76\x54\x4a\x5d\xa6\x28\xc9\xef\xa1\x68\x49\x5b\x4d\xbe\x7c\xa6\x78\x08\xd0\x4c\x58\xb8\xdd\x07\x3e\x2a\x82\xbd\x09\x81\x81\x9e\x5b\xd5\xe2\x70\xfc\x2b\xab\x7e\x3d\xe0\xc7\x64\x94\xcf\x2a\x00\x15\x6b\x7d\xc6\xd4\xe4\x1c\x33\x25\x35\x2a\xc6\xa4\x87\x22\x26\x88\xfc\xa1\xf5\xc2\x87\x6e\xd1\xbc\x07\x50\xb8\x72\xe1\x41\x0a\xe3\xb6\x00\x0f\x52\x12\x64\xaf\x53\xd8\x91\xfb\x54\x42\xa5\xbe\x03\x8c\xd2\xdf\x7e\x28\x74\x8c\x29\x24\x89\x73\x73\xf2\x28\xa4\xaf\xda\x28\x8e\x56\x2f\x31\x85\x35\xf4\x69\xa7\x50\x21\xa7\x58\x12\x4d\x02\x3d\x9f\x67\x1d\x40\x37\xc3\x72\x9e\xa7\x4c\xc6\x1e\x09\xcd\xe6\x9d\xcb\xc6\x80\x28\x0d\xee\x77\x2a\xfa\x91\xfe\x92\x97\xb3\x90\x25\x3f\xd7\xf6\x15\x45\x4e\x46\x49\xa7\x15\xa2\x4a\xa2\xab\xf1\xf4\x7e\xfc\x27\x21\x20\xd7\xa6\xe8\x7a\xe7\x72\xe9\x20\x04\xc9\x6a\xea\x92\x9c\x3d\xe9\x89\x88\xe1\xb4\x9d\x48\xe9\x27\xaf\x81\x52\x0d\xf1\x9a\xcf\x6a\x8a\xf9\xc1\x4a\xee\xe7\x82\xf1\x05\x30\x63\xf2\x11\xa9\x33\xb5\xa0\x38\x9a\xd2\xb0\x3b\x2b\x8e\xcc\x43\xe8\x89\xf5\x11\x06\x53\x5c\x0b\xcf\x1d\x4c\x28\x49\xb6\x36\x32\x9d\x72\x82\x22\x8e\x8b\x28\x2a\xf2\x0c\x11\xd1\xa8\x60\x31\x96\x91\x19\xd6\x48\xe6\x9d\x66\xdf\xee\xc1\x53\xe2\x52\x1d\x3d\xbe\x27\x76\xed\xf3\xc7\xd3\x8f\x70\x8d\x06\xf9\x82\xf7\x83\xd3\x55\x0e\xc6\x70\x5e\xc0\x23\x9d\x80\xc5\xfc\xca\x94\x79\xd0\x45\x34\x4f\x06\x7b\x67\xd2\x91\x39\xa4\xcd\x93\xf5\x77\x5e\x42\xba\xf4\x1d\xe8\x50\x31\xaa\x1d\x14\xb0\x89\x7b\x61\x25\x98\x3e\xc4\x2c\x08\xab\x85\x84\xf3\xdd\x63\x5a\xb9\xac\xa7\x31\x49\x5b\xa1\x59\x22\x17\x69\x34\x93\x23\x2c\xd4\xfd\x6b\xbf\x6b\xa1\xd1\xba\x23\x65\xd4\xc6\x5d\x11\xdd\xd3\x80\x71\x65\xd9\xee\x58\x72\xe6\xb6\x52\x54\xb6\xbb\xa9\xbb\x54\x7b\x2f\x65\x12\xd5\x04\x8b\x1d\x49\xcf\xf7\x9e\xb5\x5c\xee\xb6\xa1\xc8\xcf\x4b\x36\x70\x7c\x8f\x1b\x63\x48\x72\x81\x43\x44\x70\x3b\xe6\xf8\x12\x7c\x18\x82\xdf\x6f\x97\x01\xd4\x11\x11\x2d\xa1\x48\xe6\xe7\x1f\xce\xe9\x10\x33\x53\x63\x0f\x21\x72\x21\xcc\x43\x10\x0c\x5c\x49\xf5\xdb\x59\x03\xb9\x18\xec\x85\xdd\x09\xe1\x49\xd0\xcd\x0a\xd0\x4f\x95\x1b\x2b\x41\xc2\xf8\x15\x12\x63\xd7\x74\x7b\x98\xd0\xd4\xa9\x2d\xa9\xbf\xe7\xf2\x5e\x3f\xea\xe7\x54\x36\xdd\x85\x6a\xf1\xf3\xb4\x46\x05\xfc\x9f\x58\xbc\x49\x95\xc7\xbe\x0d\xba\x62\xc3\x88\xce\x92\x4f\x8a\xc5\x3e\xf9\xfe\x4f\x66\x2c\xbf\xec\xf7\x2f\xf3\x17\xeb\xdf\x69\xc3\x7f\x75\x6f\x11\x94\xd5\xbc\x63\x1a\x77\x50\x9b\x32\x9c\x13\xc0\xba\xa0\x69\x9c\x51\x64\x07\xd9\xfb\xee\xec\xec\xf1\xb3\x3b\xc7\x85\x09\x20\x66\x90\x98\x0d\x77\xbf\x2e\xc8\x4c\xee\x86\xc5\xe6\x59\x7b\x4e\x75\x34\x8d\x09\x08\x08\x98\xa8\x49\x9d\x7f\x93\x37\x8e\x58\xcc\xf9\x05\x05\xd0\x38\xfd\x7d\x68\x45\x51\x92\x55\x14\x54\xb6\xd1\xd5\xc5\xb5\x96\x3c\x82\xe3\x65\x2c\x67\x7e\x45\x31\xf8\x61\x00\x7b\xfb\x63\x7e\xdd\x64\x1e\x97\x0d\x95\x93\x2d\xa1\x0b\x70\x23\x45\x80\x45\x51\x9c\x6b\x1c\x58\xec\x8f\x2e\x01\xfe\x92\xa7\xa8\xf0\xf8\x42\xfb\x51\x96\x61\xba\xb6\x07\xf6\x04\x9a\xe8\xc5\xa7\xb1\x10\x73\x34\x9a\xc1\x73\xaa\x34\x4b\x30\x54\x11\xe7\xc8\x87\x13\xf3\x83\xa1\x4b\x37\xee\xc5\x25\xd1\xa4\xce\x77\x99\xd1\x96\x82\x10\xce\xb4\x80\xb6\xd0\xf0\x36\x1d\x12\x63\x28\xde\x61\x94\xf4\xd9\x98\x93\x69\x59\x5b\x31\xc4\x64\x75\x42\x26\x64\x31\xce\xf6\xd2\x5e\xf8\x2e\xf8\xae\x64\xfc\xc8\x79\xc7\x04\x54\x07\x61\xf2\x13\xa3\xa8\x69\xfe\x94\x9c\x61\x18\x74\x01\x43\x0d\xb1\x6f\x5e\x5d\xc8\x1f\x2e\xbe\x64\xea\x9e\x57\x87\xd9\xa2\x47\x00\x9b\x12\x97\x61\xc2\x53\x6a\x43\xb0\x41\x71\x5a\x3c\xc5\x2e\x9f\xa7\x8f\x6e\xf4\x76\x45\x13\x6a\x83\x6f\x38\xd1\x1d\x8c\xa2\x08\x59\x4b\x85\x8b\x8a\x3d\xe0\x24\xcb\x93\x12\xe4\x75\xef\xfd\xf6\x3c\x95\x73\xfc\x2b\xef\xd6\x50\x55\x95\x8b\x7a\xc1\x23\x0c\xae\x35\x05\x04\x5b\x3b\x89\xa8\x1a\x72\xdd\x46\x71\x48\x55\xf5\x10\xfc\x72\x18\x0d\x6d\xc3\xdf\x7f\x85\xef\x78\xdf\x93\x82\xc0\x0c\x49\x21\x43\x08\x52\xee\x49\x65\x23\xd1\xd7\x02\xe3\x75\x83\xcc\x62\x93\x5b\xd4\x40\x42\x9e\x5b\x96\xc0\x94\xb5\xbc\x4f\xc1\x57\xf0\xf8\xa9\x3b\xaa\xac\x6b\xec\xfd\x46\xd1\x1c\x24\xc4\xdc\xe5\xd5\xa4\xaf\xb0\x29\x8c\x12\x49\x1a\xa8\x42\x27\x90\x7a\xa3\x22\xa5\x09\xc1\x6c\x7a\x0a\x50\x39\x28\xed\x23\x90\x5a\xe1\xf8\x1a\xec\x04\x3d\x50\xdc\x8c\xf0\xfe\xec\x14\x50\xde\xf2\x73\x97\x37\x6b\x81\x49\x7f\x91\x6e\xcf\x23\xf6\xae\x04\x4f\x15\x66\x96\xde\x00\xd8\x35\xe8\x20\xa7\x25\xc7\x8a\x06\x86\x6d\x28\xb9\x77\x7f\x48\x49\x27\x2d\xd4\xfa\x23\x3b\xba\x7b\x3d\x03\x3c\x76\x35\x10\x7b\x05\x1c\xfd\x4b\x37\x81\x0b\xd4\x73\x20\xfd\xef\x07\x7f\x59\xcb\x25\x23\x4b\xc8\x2a\xe3\x0a\xf6\x5d\xe7\xb9\xc1\x7e\x3a\xfb\xed\x79\xa0\x85\x0a\xb4\xb1\x8d\x33\x14\x80\xf7\x34\x51\x90\x64\x0a\xb3\x59\xab\x76\x6b\xb1\x4a\xe4\x8d\x34\x66\x19\x1f\x82\xc9\x25\x67\xa2\xf9\x3b\xf8\x5d\xf3\xeb\xd0\xfb\xa9\xd5\xa6\x34\x60\xee\x9a\x77\x5f\x8c\xa2\xc2\xe8\x95\x8d\xee\xd9\x9b\xb7\x27\xe5\x71\x58\xc8\xca\xf7\xdc\xb2\x71\xac\x68\x4b\x91\xb8\x31\x4f\x3b\x1f\xdb\x61\x71\x53\xb4\xd3\x50\xd2\x80\x0e\x70\x3e\xc3\x18\xdb\xfd\x02\xe9\x37\x9e\x6c\xf3\x8f\x56\x37\x7f\xf9\xbf\xcb\x6d\x74\xff\xff\x42\xc7\x26\xfc\x27\xdb\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\x39\x1f\xff\x32\x81\x52\x85\xff\x65\xcf\x10\x6c\xff\xa7\x70\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\xd5\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\xea\xf7\x57\x5d\x43\xb1\x85\x22\x01\x36\xac\xc9\xbc\x72\x0f\x6f\xff\xbc\x1f\xc7\xf2\xf8\x4f\xc5\x31\xc3\xdf\x60\x25\xb3\x6d\x82\x1c\x63\xc9\xb1\x5d\x1a\x95\x6b\xde\x43\x1d\x49\x9e\xa0\xd2\xb1\x6b\xca\x43\x5d\xf8\x85\xa6\x21\xc0\xb7\x83\x84\x4b\x16\xb4\x44\x31\x85\x7e\x35\xe0\x41\x82\xae\xbf\xe4\x1b\x07\xa5\xa7\x00\x85\x7f\x30\x6b\x6e\x8f\x42\x82\xc7\x52\x12\x9a\x4a\x82\xf7\x7c\x36\x88\x8a\x87\xba\x24\x72\xaf\x64\x0a\x88\x3f\xfe\xce\xa3\x10\x4a\x3c\xaa\x53\xe4\x86\xa8\x24\xf8\x2e\xa5\x9d\x56\x06\x71\xc8\x11\x75\x54\xc4\xd6\x0c\x38\x96\xcf\x51\x75\x54\xf8\xe0\x34\x5e\xb8\x37\x78\xe1\x51\xf8\x04\xd1\x7b\x01\x32\xfd\x04\x31\xbc\xbb\x31\x7a\xe6\x31\x3a\xea\xfe\xe3\x32\x3b\xe8\x31\xf9\x05\x36\xfb\xe5\x35\x5f\xa6\x51\xb8\xff\xba\x7a\xac\xb1\x65\x75\x48\xfb\xd5\x73\x85\xe4\xbf\xc7\x53\x4c\xee\x64\x7b\xea\x52\xca\xee\x6d\x75\xd4\x55\xa2\x25\xaa\xcf\xc5\xa7\x4f\xf4\x9b\xbe\xd4\x63\xf9\x03\xae\x7f\xcc\xab\x7f\xca\xab\xc7\xea\x90\x76\xf0\x57\x45\x38\x94\xc4\xcd\x91\xcf\x46\xff\x37\x5c\x21\x8d\xcd\x3f\x02\xd9\x5d\x4a\xe3\x95\x77\xec\x9b\x4a\x09\x91\x44\xea\x55\xc6\x0e\xad\x74\xca\x5f\x73\x20\xc1\xf7\xdf\x9f\x99\xcf\xc6\xf9\x5f\x73\x72\x26\x08\x7d\xe8\x68\xdb\x16\x1c\xf5\xe8\x3d\x73\x29\x1d\x8b\xe5\xd1\x73\x16\xdf\x8a\xe5\x31\x6b\xfa\x3e\xd4\x65\xb2\x0b\x15\xfc\x72\xe9\x08\xfe\xe9\xd3\x9f\x73\xa5\xff\x67\x3d\x69\x2c\x89\x99\xcb\xf0\xb0\x5b\x47\xe0\x43\x7f\xff\x7a\x66\x81\xba\x5e\x1a\x25\xb4\x32\xb5\x50\x29\x33\x84\xfe\xd2\x67\xf1\xfe\xf7\xfa\xf7\x39\x02\x5d\x95\x24\xde\xfa\x27\x9c\x06\x47\x7f\xa1\x3c\xde\xa9\x47\x7b\x69\x6c\x5e\x65\xac\xf6\x7f\xec\xa5\xb4\x33\x3a\x45\x6e\x8f\x82\x5f\xf9\x62\x0a\xdb\x52\xa2\xdf\x50\xa2\xaf\x9c\x87\x3a\xe7\xcf\xf1\x37\x81\xd4\x5e\xa5\x44\x7f\x99\x44\xdf\x8a\x60\xfa\x66\xc7\x2c\x21\x32\x9e\xa9\x44\xa3\xc5\x3b\xfc\xf9\x7b\x01\x36\xad\x61\x3c\x0b\xd4\x6d\xf3\xc9\x1c\xbd\xc0\xa1\x95\x3f\xf6\x0a\x87\xaf\x59\xe4\x10\x06\x6f\xf2\x86\xcf\xb2\x06\xa4\x4a\x86\x2f\xe0\x86\x2f\x8a\x86\xdf\xa0\x26\x64\x8a\x96\xaf\xbc\x86\xef\x20\xce\xd7\xb2\xe6\xe0\xfc\x0d\xcf\xbd\x12\x34\x3c\xd2\x08\x87\xfe\x86\x37\xfc\xaf\x78\xe6\xff\x88\x67\x77\x0c\xf5\xc7\xfa\xf8\x01\x44\xb8\x52\xf8\x66\x71\x3a\xa6\x42\xfa\xe6\x08\xd4\xfc\xd7\x1c\x12\x59\x84\x7f\xa5\x24\x9e\x09\x12\xaa\x2e\x0f\x75\x7f\xdc\xaf\x4f\xe3\x9a\xf2\xcb\x6d\x40\xc6\x63\x08\xc2\x67\x05\xc9\x63\xf8\xc3\x63\x04\xc1\x63\xf1\x05\xea\x40\x01\x6e\xf4\xca\x63\xf2\x29\x6f\x09\x02\xe2\x72\xca\x7f\xe3\xa5\x12\xdd\x97\x11\x3c\xe6\xb3\xfb\x37\x3c\xf7\x7f\xc1\x73\xfe\x67\xbc\xeb\x8f\xb1\xeb\xe8\xff\xc5\x5e\xfc\x63\x8f\x72\xf4\x7f\xf6\x63\x30\xb8\xd2\x9f\xf7\xfd\x69\x6f\xff\xb1\x3f\x1f\x6b\x6c\x9e\xc6\x0a\x49\xec\x33\x24\x84\x14\x29\x3c\xff\xb0\xf3\xa2\x53\x40\x7b\x21\x91\x38\x28\x18\x86\x51\x0b\x2f\x70\xd9\x50\xee\xb3\x56\x54\x4b\xff\x31\x59\x91\x87\xf3\x77\x28\xc0\xe3\xb8\xca\xe3\x38\x22\xa9\x51\xa0\x3c\xf9\x05\x0d\x9f\x2e\x66\xb2\xb9\x2a\x04\x63\x83\xe1\xc6\xf2\x75\xb3\x60\xeb\xf8\x32\x78\x8b\xad\xe1\x0a\x6a\x2d\xb2\xce\xc3\xf6\xad\xe1\x2a\xa2\xe0\x78\x1c\x33\x3a\x8f\x96\x48\x4d\xd3\x05\x68\x85\xca\xf9\x5c\xc7\x48\x2e\x1e\xb0\x10\xd0\x03\x3d\xd1\x53\x3e\x7e\xf8\x8a\x7d\xe3\x27\x9a\xc2\x93\x4c\xeb\x59\x81\xfd\xe4\x7b\xe9\x8d\xdb\x29\x33\xc2\x06\x73\xf3\x3e\x54\x90\x16\x89\xdc\x97\x5d\x9e\x65\x65\x66\x83\x6d\x1e\x56\x0a\x1d\xbb\x41\x16\xd7\x57\x5a\x05\xfe\x9a\xb8\xce\x33\xbb\x2f\xba\x8c\x3a\xec\xe0\xc0\x21\xf6\x23\xba\x61\x85\xd2\x5e\x47\xd4\x58\xfe\x56\x1f\x81\x08\x2b\x23\xc8\x60\x63\x9a\x30\x25\xe2\xa8\xdb\x81\x56\xf1\xd4\xa4\x75\x94\xba\xb1\x6a\x3e\x86\xec\x60\x6a\x37\x70\xa1\x78\xea\x0a\xda\xd0\xd1\x40\x3e\xfb\xe9\xdc\xa2\x51\x3c\x59\xc9\x2d\xe6\x0e\xba\xae\x62\x05\xf7\xc1\x08\xd3\x1b\xf1\xdd\x54\x1f\xf5\xb6\xdb\x11\x2e\xa8\x99\x6f\xae\x36\x16\x4f\xe1\xe9\x30\xd1\xa4\xb7\x8a\xb8\x2f\xa5\x85\x05\x35\xa4\x16\x24\x97\xbe\x36\x06\xee\x0c\x50\x12\x61\xf3\x88\x97\xb6\xba\xe1\xf4\x34\x11\x31\x9d\xc1\xb4\x88\x1b\x8b\x89\xa6\x90\xd4\x58\xa8\xc5\x43\x47\x09\xcb\xbd\x85\xc2\xcd\xab\x99\x2f\x7d\x10\xad\x3c\x9e\x40\x1c\x96\xb6\x08\x0f\xdd\x44\x1b\x15\x24\x74\x3a\x29\x07\x28\x51\xed\xa4\xbf\x58\x84\x94\x5d\xbe\x12\x60\xaa\xd8\x12\xa2\xda\x8c\x69\x97\xd0\x30\x1c\x51\xd5\x22\x91\xb4\xcd\xd4\x00\x86\xb1\x75\xdf\xa5\x91\xda\x7c\x7b\x2c\x25\x66\x0c\xeb\x10\x6e\x89\xd9\xf8\x2d\x2c\x9a\x3c\x1c\x06\x01\xc0\x83\x5d\x60\xa2\xec\xaa\xa1\xec\x43\x0e\x28\xdd\x2e\x0d\xd9\xb2\xbc\x25\x94\x00\xed\x97\xee\xe3\x6f\xbf\xb9\xab\x1e\xd6\xcb\xb0\x56\xe3\xa1\xcc\x35\x6a\x3a\x10\x67\xc8\x5e\x8b\xa6\x19\x08\x84\x8e\x9f\x83\x11\x0a\x3c\x86\x45\x0c\x04\xae\xd0\xce\xbb\x8d\x62\xaf\xbe\xc2\x0c\x0f\x3f\x5d\xce\x1a\xe7\x7c\xac\x5f\x40\x4d\xea\xdb\xa1\x7e\x01\x5b\x18\x30\xd2\x01\x44\xcc\xe4\x43\x39\x20\x65\xcb\x1f\xcc\xff\x7e\x8c\x7e\x50\xc7\xf8\x83\xb8\xdf\x90\xab\x86\xec\x2f\x2b\xed\x0d\xf8\xae\x67\x70\x43\xe9\x00\xe3\xaa\xe5\xec\xb5\x1a\x37\x26\xe8\x71\xce\x26\x41\x1f\x78\x27\xe9\x89\x3f\x72\x47\x36\xf4\x62\x42\x36\x8f\xc9\xb0\xa5\x89\xb2\x28\xc9\x66\xdb\xb6\x24\x3e\xb5\xbe\x31\xd4\xcd\x98\xe5\xe6\xee\xa0\x30\x18\x91\x8c\xbc\x9b\x07\x7e\xce\xa6\x88\x9a\x83\xf6\x8d\x6d\x9d\x26\xce\xd9\x5a\xac\xf6\x42\xaf\x65\xfe\x6b\x28\xbe\x67\x2c\x76\x17\x1b\x41\x57\xa7\x5d\xda\xc9\x2a\x1a\x86\x02\xcf\x4f\xf0\x61\x1b\x46\x1e\x22\x8e\x08\x6c\x86\xf7\xad\x7f\x94\x4c\x14\xff\x87\x4c\xfc\x1f\x32\xf1\x7f\xc8\xc4\xff\x63\x32\xe1\x0e\x06\xe6\xf4\xc9\x6b\xf2\xe1\x1f\xc1\x1f\xfb\x33\xf8\x8f\xac\x2b\xa4\x9c\xc9\x9b\x82\x01\x09\x7f\x04\x56\xc8\x08\x94\xff\x2d\x32\xf1\x17\x5e\xfa\x3f\xe2\xfd\xbf\x23\x13\xab\xe4\x7c\x2d\x67\xf6\x0a\x64\x40\x7f\x04\xff\xe6\xcf\xe0\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\x3f\x6d\xf9\xcf\x0f\x48\xdf\xd8\x18\x96\x0c\x36\x59\xd7\xca\xbc\x61\xf5\x59\x01\x41\xed\x36\x45\xf0\x62\x1b\x91\x17\x2f\xcf\x8b\xb1\x83\x52\x12\x3d\x58\x7c\x14\xd7\x65\xe3\x74\x14\x1d\x5a\x0a\x4b\x5e\x30\x95\x56\x52\x9f\x81\xdf\x6f\x64\x9a\xab\x74\x36\x28\xf4\x77\x9a\xe9\x68\x4d\xe6\xc2\xb7\xdf\xf8\x7d\x68\x09\xd2\xdf\x85\x7a\xcb\xfd\x50\x5c\x0b\x6e\x63\xa2\x21\xb1\x81\x16\x82\xba\xe7\x32\x04\x6c\x7d\x08\xfe\x4a\x02\x3c\x89\xcc\x84\xa9\x9c\x74\x0d\xd1\x07\xe8\x6c\xd9\x6d\x50\x78\x00\x28\xab\xc0\xf5\xbc\xc9\x1e\x25\xec\x51\x13\x0c\xe6\x2b\x0e\x4d\x45\x33\x49\xcc\x26\x43\xee\x43\xa8\x04\xee\x42\xea\x8e\xc1\xf8\xad\x51\xb4\x12\x6d\xa8\x14\x9d\x30\x20\x06\x63\xdd\x79\x10\xf5\xcb\xfe\x40\x41\x27\x2e\xd1\xa6\xae\x92\xf1\xe0\xbc\xf9\x59\xfc\x86\x67\x8a\xbd\x64\x14\xc2\x44\x6c\x03\x8e\xaf\xa6\x1b\x32\x6c\x1b\x2b\x98\xd1\xf1\xa5\xc7\xfa\x27\xc1\xc5\x29\x8e\x6c\x16\xad\x9d\xf6\x64\x8a\xed\xe9\x09\xc1\x65\x1c\x8d\x36\x8d\xd3\xbf\x9d\x93\xba\x43\xe5\x78\x9f\xee\x2e\x97\x94\xd9\x45\x17\xe9\x07\x5e\x67\x5e\x24\xb0\x4b\x4b\x68\xec\x65\xb5\x5d\x66\x36\x19\x04\x24\xf4\x7a\x67\xe2\x73\x9d\xe4\xaf\x5e\x29\x11\x5f\x23\xfe\x00\x36\xd3\x58\x11\xa5\xeb\x65\xe9\x2e\xcb\x88\xbb\x4c\x00\x45\x41\x6e\x61\x2c\x1b\x9f\xc3\xd2\xa7\xbd\x72\x71\x60\x75\x68\x9a\xce\x21\x92\xeb\x47\x86\x04\x04\xd0\x1f\x99\x0d\x0c\xd2\xd4\x32\x5d\xb8\x22\xd5\x5a\xb8\x88\x87\x15\x36\x3a\x8c\x48\x9f\xa7\x06\x6c\xe2\xfe\x8e\xc3\xb7\x3b\xcf\xaf\xc8\x9c\x09\xc2\xda\x32\x1a\x5c\x0a\x35\xbe\x7a\xa5\x7f\x0e\x5a\x33\xe2\x77\xd2\x76\x4b\x00\x91\x51\xf7\x23\x01\xae\x12\x5b\xe6\x48\x9f\x6b\xd3\x43\x39\xa3\xdb\x47\x2f\x7e\x0d\x6f\x1b\xa4\xac\xdd\x58\x95\x64\xca\x26\xcd\xe4\xbc\x2e\x05\x1f\x21\x57\x48\x1b\xf6\xa8\x3e\xd2\x1c\x05\x56\xd7\x5e\x36\x99\xa1\x41\x72\x48\xe5\xc5\xc4\xfb\x01\x14\x04\x6c\x12\x17\x55\xe9\x02\xa6\x2e\xcd\x32\xa4\xa0\xfd\xc5\x0f\xb0\xbb\xbf\x18\x21\xda\x18\x07\xc2\xec\xf1\x2b\xe7\x83\x93\x64\xb3\xb3\x98\x2f\x4a\x1b\x41\x73\x70\xe7\xc0\x47\x65\xd3\x97\x3e\xcf\x62\xcf\xf1\x0b\xf7\x45\xac\xdb\xc7\xbc\x74\x1b\x20\x25\x61\xac\x66\x08\xa3\x40\x00\xc6\x27\x06\xbf\x1c\xe2\x57\xd1\x5c\x07\xff\x9b\xd2\xa9\x16\x8f\xaf\xba\x5b\x39\x29\xea\x3b\x48\x18\x23\x9d\xc2\x2c\x75\x46\x5d\x94\xff\xc9\x44\xe0\x68\xb2\x7f\x97\xed\xfe\xdf\x1c\xff\x8e\xe0\x1a\x82\x28\xba\x2b\x75\x6b\x8e\x20\xab\x21\x11\x6a\xe1\x09\x8e\x9f\x07\xca\x3d\x2f\xdf\xb3\xb2\xc5\x55\xad\x95\x60\x43\x9a\xbd\x34\x85\x0f\xde\xa3\xe9\xc3\xe4\xa0\x68\xb9\x30\x71\xad\x18\x24\x9a\x14\x1e\x3a\xe4\x22\x8d\x7e\x98\xdc\x88\xa6\x70\x8a\x02\x9f\xc7\x8c\xcb\x3c\x55\x9f\x55\x81\x16\x40\x93\xe8\x75\xa5\xc2\xfe\x62\x6a\x32\x6f\xa5\x6d\x9c\x84\x3b\x78\x4e\xe2\x20\xb4\x2a\x0c\x2c\x60\xa7\xc5\x6f\x1f\x7f\x87\xdd\x3a\x23\x82\x86\x69\x41\x81\xc7\x8f\x56\xe0\xd7\x90\x1b\x48\x60\x28\xf9\xc7\x1a\x10\x36\x86\x22\xd3\x2e\x09\x4a\xd5\x9e\xc7\x3b\xa1\x89\xae\xb5\x16\x52\x12\xa9\x15\x4f\x2a\x8f\xc4\x05\x3f\xf9\xb8\x05\x68\xa5\x17\xe8\x8a\x84\x62\xda\xff\x08\xa0\x71\x9a\x7b\x9f\xdb\x4f\xf2\xcf\x8d\x30\xdb\x9d\x18\x92\x74\x8b\xfb\x5b\x87\x24\xb1\x15\x46\x34\x20\x20\xab\x9e\xef\x68\x87\x25\xe9\xf8\x05\x9a\xe9\xee\xda\xb0\x56\x8a\xc2\xae\x9a\xe2\x1e\x0a\xac\x92\x45\x4c\xb6\xb1\xdb\x16\xa0\x61\xb5\xf1\x8d\xf3\x03\x97\x4a\x12\xf2\xc5\x4c\xd6\x7f\xa2\xb2\xb0\xc6\x35\x37\xf0\xbb\x2a\x9a\xb5\x4d\x36\x0a\x49\x11\x6a\x29\x42\xd1\x4d\xcb\xf5\x8d\x8f\xfb\xe2\x6e\xc3\x88\x37\x2f\x30\x8a\xc5\x0f\x5c\x31\x29\x46\xd9\x39\xfa\x6e\x96\xd1\x6d\xa4\xa5\x3a\x36\xd4\xfa\x09\xc1\x01\x67\x6c\xab\x6d\x68\xdc\xcd\x8f\x96\x6c\x22\xfd\x3a\xf9\xe6\x2a\xdb\x6e\xbc\x00\x24\xbd\x2f\x46\xe6\x5a\x13\x44\xb1\xa7\x1f\xbc\x60\x0a\xf8\x5d\x1e\xe7\xe6\x30\xfe\x84\x43\x22\x1c\xce\x76\xee\x4a\x95\x70\x53\x72\x9c\xe6\x5d\x48\xd5\x3b\x7f\x29\xf4\x58\xf6\x27\x7d\x31\x3c\xf3\x76\xad\x2e\xe4\xbf\x88\x49\x5b\x6b\x09\x57\xf4\x23\xba\x8d\x0d\x3a\x16\x66\xb0\x59\xa8\x6f\x4e\xd8\xf3\x41\x07\x0d\xcc\x6f\x04\x7c\xc6\x7b\xfe\x01\x16\x5f\xf8\x56\xb8\xa4\x26\xfa\xe0\x28\x99\x30\x32\x86\x85\xba\xe9\x7b\x20\x33\x00\x23\x2d\x48\x04\x60\x5c\x84\x37\xbb\x79\x76\x41\xce\x8e\xf0\xa5\xda\x27\x18\x93\x79\x7e\xd7\x43\x91\x4d\xc2\x49\xdc\x13\x0b\x5a\xa8\x5e\x5c\x24\xee\x12\x5a\xb5\xf0\x65\x82\x2a\x66\xf1\x84\x55\x62\x01\x47\x2d\x90\x84\xfa\x31\xe9\x4b\xba\x7c\x2b\x74\x27\x38\xd3\x25\xd2\x31\x21\xb6\xa4\x88\x81\x5d\xf2\x02\x52\xa1\x5b\x86\x37\xd6\x42\x23\xed\x36\xb4\x95\xa6\x35\xc5\x10\xdb\x49\xda\x1a\x0e\x21\x9c\xdf\x20\x3c\x47\x48\x0e\x36\xdc\x5a\xc3\xb6\x5f\x28\x40\x42\x56\x0d\xb1\xee\x80\x84\xe5\x12\x66\xbb\x34\xed\xf5\x4c\xb8\xd0\xb2\x80\x6d\x40\xad\x99\x02\x74\x8d\x78\x76\x9f\xde\xd2\xf6\x55\xd7\xe7\x6e\x55\x87\x3d\x73\x04\x8d\xe0\xb8\x1a\x99\xb4\x1d\x6d\x69\x33\x39\x6b\x51\xfa\x3c\xa3\x67\x47\x23\xea\xdc\xcd\x9c\x29\xbf\x88\x72\x8c\x96\xc7\x31\xe4\x0a\xf2\x07\x8c\x30\x7a\x22\xf7\x0d\xbb\x30\xc5\x60\x58\x6b\xeb\x50\xa1\x27\x73\xe6\xcf\x77\x81\xff\x9c\x86\xf0\x68\xbe\x7f\x99\xef\xf8\x7b\xeb\xd2\x7f\xda\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\x93\x10\x4c\xee\xdf\xcf\x72\xfe\x53\x49\xb8\x25\x9f\x1c\xed\xc7\xf8\x4b\x54\xb3\x88\x02\x61\x7c\x03\x75\xcf\x4c\xa9\xa5\x59\xa8\x81\xf5\x05\xba\x68\xe1\x25\x29\x21\xff\x85\x0f\xdb\xc6\xa7\xec\xb5\x13\x82\x27\x12\xab\xba\xce\xca\x24\x2c\x2f\x44\x6b\x26\xd8\x42\x3b\xec\x65\xb8\xe6\x6f\xff\x5d\x95\x85\x19\x75\xca\x73\x7e\x94\x67\x67\x55\x17\x24\x4a\xd8\xca\xd7\x59\x0c\x49\x5a\xb6\x8c\xbc\x2a\x57\x78\x52\xd9\x20\xe7\xb0\x3b\x8c\xb6\xd4\xe2\x72\x82\x64\xf8\x3b\x18\xcf\x5d\xaf\xd0\x7c\xe7\x1e\x46\x6b\x22\xb6\xda\xbe\xa1\x64\x66\x34\x7c\xc5\x29\x5f\x50\xb7\x80\x0b\x3d\x93\xc0\xf6\x07\x46\xe6\xfc\x1c\x28\x34\x00\x5a\xcb\x57\xd2\x08\xa0\xcd\xaf\x13\x03\x9f\xee\x95\xf3\xb9\x48\x98\xbb\x76\x61\x3a\x6d\x72\x09\xe4\x17\x8b\xd6\x77\xaf\xa9\xfc\x92\x56\xe3\xe5\xa9\x5f\x43\x42\x7e\x97\xc3\x97\xec\x78\x2b\x69\x76\x3a\xf8\x59\xb7\x30\x72\xdc\xdd\x12\x60\x02\x30\x27\x01\x6c\x2a\x2e\x67\x2a\xfc\x0e\xb0\x07\x42\x4d\xf1\xf7\x50\xa1\x79\xa6\x24\x4d\xf4\xf4\x06\xf2\x0d\x73\x2f\xd3\xbd\x71\x63\x37\x32\x93\x08\x89\x02\x76\x73\xca\xcc\x8c\x43\x6f\x61\x2f\xf0\x83\xd4\xc6\x8c\x91\x65\x27\x62\x3b\xf1\x90\x0d\x2c\x9c\x97\x29\x9c\xec\x10\x7b\x06\x62\x6d\x99\x30\x93\x6e\x2d\x0a\xe6\x56\xa4\xe0\x45\xb8\x50\x15\x53\x65\x1e\xb4\xf1\x55\x99\xed\x41\x7d\x0c\x54\x0c\x69\x52\x87\x2a\x52\x22\xef\xc3\xb5\x46\xc1\xd7\xb2\xcd\xd1\x97\x8f\x3d\x9c\xf7\xb8\xa4\xa5\x7e\xbe\xc2\x53\x3b\x74\x57\x4f\x15\xf2\x90\x74\x18\x25\x85\x6b\xc3\x50\xd5\xe2\x13\xd4\x02\x46\x1a\xb0\xb9\x0c\xb9\x3a\xb0\xaf\xe0\x8c\xc4\xa1\x03\xcb\xc9\x28\x80\x11\xdc\xb9\xd8\xce\x49\x9e\xa9\x5a\x01\x7a\x5b\x03\x3d\x98\x8c\x55\xbc\x2b\xf1\x0c\x4e\xd4\x81\xc5\xb0\x0c\x0d\x4a\x3b\xb7\x66\x8a\x7c\xff\x28\xd1\x6a\x1d\x0a\x41\x2d\xdc\xad\x23\x82\x38\x02\x89\xe1\x5b\xf3\x45\x5d\xd3\xe5\xfb\xc2\xc4\x60\x59\x7f\x4a\x87\x52\x89\x3e\xf1\x77\xcb\xd1\x6b\x4b\x65\x35\xac\x06\x76\x04\x3c\x97\xec\x68\x17\x53\xd2\x7c\xd8\x38\xc4\x2a\x94\xd3\xa7\x8c\x7c\x21\xad\x85\x0d\xbc\x0d\x6d\x44\x7f\x9c\x6a\x29\x9f\x1f\x12\x0c\xbf\x23\x2e\x7e\x8e\x09\xcf\x9b\x43\xd2\xaf\x10\xdf\xfe\x44\xe0\xe3\xc2\x66\xb8\x51\x18\xb8\xe0\xe0\xe9\x9d\x74\x30\x43\xc8\x63\xf8\x12\x59\x60\x43\x39\x0b\xba\x99\x12\x00\x1c\xf4\x27\x87\xc0\x40\x5c\xe4\xca\x2e\x69\x06\xde\xbe\x2a\x58\xb4\xb5\x1b\x1f\xfa\x29\xf4\xe8\x6b\x1a\xe0\x04\xbf\x2a\xac\x4f\x67\x1b\x0c\x3a\xe7\x4c\xf8\xdd\x7f\x91\x16\x3f\xe5\x61\x37\x97\x57\xdc\x01\x33\xe1\x54\x9c\xe2\x48\x04\x13\xce\x6b\x1f\x5d\xed\x06\x5f\x87\x53\x94\x94\x0b\x1d\xfc\x1d\xb2\xbd\x5f\x37\xc3\x61\x27\x47\x6f\xed\xbc\xa7\xd7\x3f\xdc\x94\x70\x3c\xff\xb2\xae\x84\x4a\xfd\xef\x42\x42\xf0\x3b\x2c\x09\x16\x1c\xbb\xde\xdf\xb8\x7b\x3f\xb6\x39\x15\xd5\x7b\xb9\x36\x65\x59\x41\xe4\xb4\x55\x93\xf5\x85\xa8\x9a\x55\xf8\x99\x33\xc5\xc9\x8d\x4c\x35\x43\xaa\x74\xbe\xa7\xc4\x7a\xab\x32\x11\xd7\x0c\x8b\xd1\xb8\x86\xd7\xb9\xac\xa7\x21\xf4\x87\xbd\x34\xa0\xc0\x25\x28\x73\x3f\x31\x47\x0d\xdf\x9e\xe7\x7e\xf8\xc6\xd5\xf1\xde\x39\x01\x6a\x9b\x84\x6a\x49\x44\x1a\xe7\x64\x5f\xee\x23\xc6\xba\x2c\xe9\xe0\xfc\xd5\xd7\xef\xd7\x57\x3b\x41\x12\x48\x95\xa3\xc7\xe7\x10\xf4\x29\xaa\xb7\xbd\x6f\x96\xcd\x01\x06\x2b\x4c\xcf\xb3\xb6\x1d\x76\x8c\x01\x6e\x49\xd3\x6e\x7d\x19\x1b\xe9\x05\x60\xd1\x8b\xa2\x84\xad\x57\x74\xe5\xf0\x4a\x29\x75\xc9\x04\x32\xcb\x87\xa7\x8d\x99\x82\x15\x7b\x45\xf8\x3d\x53\x7b\x99\xc8\xb2\x45\xb1\x40\x42\xb4\xbd\xd7\x77\xe6\xd3\xfa\x3a\xbf\x1e\x14\xe3\x81\xc4\x0b\x27\xf3\x04\xa3\x32\xe2\x80\x7a\xde\xc1\x66\x40\xb9\x2f\x41\x02\xd4\xdd\xe2\xed\x85\xf5\x40\x3a\x52\x66\x2a\x8c\x41\xfc\x4a\x4f\x23\x2d\xb0\xd4\x2c\xd4\x9f\x1e\x21\x7b\x0a\x46\x05\x59\xd2\xb8\x38\x63\x54\xe1\x39\x41\x8c\xb5\xca\x8e\x11\x78\x88\xfa\x75\x0e\x8f\xfc\x3a\xeb\x57\x3d\xaf\xbb\x24\x05\xca\x5d\x3b\x93\xeb\x12\xc3\xf4\x69\x93\x91\x57\x93\x4a\x08\x1a\x19\x5c\xc9\x5e\xcb\xa3\xa9\x05\x4a\xf8\x2e\x3b\x1a\x5d\x96\x21\x2a\xfb\xf6\xe6\xb6\xf1\xd4\x36\x24\x05\xbc\xf6\xbc\x46\x66\x79\xf5\x02\x60\xd2\xfe\xa2\xb1\xd6\xf6\xbb\x5d\x3b\xce\xa5\x89\x4c\x08\xe8\x05\x07\x1c\x01\x6d\x90\xe5\x0a\x23\x7e\x42\xbc\x02\x41\x72\xd6\x99\xa8\xeb\x17\xae\xf9\xe0\xd1\x3f\xa0\x5c\xec\x1f\x2c\x58\x51\x9a\x39\xd0\x2b\x2e\x4f\x83\xd8\x85\x2b\x2c\xbb\xc0\x28\xd8\x79\xa5\xad\xba\x7e\xa2\x61\x03\x85\x17\xbb\xf9\x06\x40\x18\xea\x1a\xd9\x5c\x7d\xc0\x61\x46\x9a\xa1\x10\x92\x09\x35\x50\x0a\x61\xb2\xe8\x02\xe6\x62\x72\x20\xf4\x3e\x24\x4c\x56\x75\x6a\x79\xf9\x97\xa0\x4c\xe1\x62\xd6\x8a\x30\x12\x83\xaf\x60\x84\xc2\x3f\xba\x82\x2e\xb3\xf1\x7e\x2d\x6d\xdd\xdc\x6f\xad\xb8\x61\xbb\xd2\x73\xf3\xdf\x7c\x5e\xdd\xed\x01\x7f\x08\xd7\x5f\xd7\xcd\xf0\x8c\xca\x81\xe4\xf8\x31\x9f\x33\xdd\xff\x64\x20\xbe\xb3\xeb\xdf\x65\x6b\xab\xf8\x77\xf2\xfe\x1f\x29\x9f\x1d\x1f\xab\x96\xc7\xd0\xbd\x05\x8e\x16\x3a\x86\x58\x2a\xb1\xc3\x9a\x9c\xc3\xee\x10\xa1\xd9\x00\x4b\x59\xbc\xd4\x02\x46\x8d\xe5\x20\xa6\xec\x92\x80\x63\xc3\xd3\x16\x06\xfb\x1b\x56\x32\xb1\x9c\x86\x75\x2f\x4f\x93\x48\xb4\xbe\xf6\xdf\x41\x59\xc7\x92\xed\x03\xf4\x4c\x25\x90\x93\xdf\xfa\x7c\xd7\x44\x09\x28\x58\xb8\xbd\x3d\xcc\xdd\x7b\x8e\x11\x64\x8a\x2f\xa2\x2e\xfc\x20\x30\xcd\x69\x8d\x6b\xac\xd2\x2b\xaa\x53\x06\xbb\x85\x23\x66\xd1\x89\xfc\x64\x15\xb5\xc6\xa7\x3b\x16\x92\x45\x6a\xb6\xde\xd6\x3e\x1f\x06\xdb\x1d\x34\x5d\xa3\x1a\x2f\x16\xb5\x13\x31\x0a\xb1\xdc\x3f\x49\x8d\xc6\x33\xfb\xba\x26\xe4\xb0\x20\xa2\x65\x32\x99\x1f\xc6\x18\x3c\x8b\xab\x32\xc5\xbb\x69\x6d\x69\x65\xed\x41\x02\xbc\x8a\xd1\x33\x80\x14\x97\x3f\xdf\xef\x1c\x17\x7b\x0e\x0c\xfa\xad\x62\xbf\xa6\x9e\x0c\x9e\x97\xa2\xed\x9a\xab\x98\x4b\x3d\xda\xe4\xc9\x69\xb9\xf0\x96\x36\x79\x0a\x37\xe8\x97\x22\xf8\xf5\x58\xf0\x5f\x30\x9c\x2a\x66\xbf\x68\xc2\xab\xeb\x4b\x38\x92\x6a\x67\xef\xc6\x02\x66\x5f\x03\x18\x1a\xeb\x08\x02\x1d\x50\x71\x5b\xe9\x50\xff\xcc\x78\x67\x83\x2d\x3d\x1b\x9e\x21\xb8\x5c\x2f\x99\x8e\xb9\xb3\x6a\x80\xd3\x80\xd6\x27\x9b\x72\x5b\xc2\x23\x29\x69\x97\x9e\xde\x5a\x69\xb1\xfc\x34\x35\x0b\x53\xa5\x65\x1b\x89\xf1\x3e\x0d\x81\x6f\xf0\xce\x7f\x33\x37\x50\xd5\x19\x03\x82\xc1\xf4\x59\x96\x9e\xb6\x5c\xde\x41\x29\x87\x62\x32\x9e\xa7\x64\x4b\x9c\xe5\xde\x77\xd2\x37\xf8\x6f\xb3\xee\xa2\x70\x07\x00\x0d\x1e\x48\x11\xae\xf9\x98\x76\x53\xc2\xd2\x29\xc8\x5e\x1d\xbc\x99\x5b\x93\x03\xb3\x4e\x6b\x5f\x33\xa1\xd4\xcd\x6e\x9a\x5b\x6a\x6a\x53\xc1\xd5\x60\x5e\xf9\xc5\xb5\x81\x31\xfc\x61\xf7\x04\xf5\x98\x8d\x6a\x36\x48\xc1\x08\x8d\xec\xce\xab\xde\xf8\x54\xb7\x25\xc8\x3c\x16\x92\x4e\x89\x05\x26\xf4\x23\x1c\xf2\x04\xa6\xfd\xb6\xbb\xde\x7e\x6c\x11\x3f\x58\x68\xb5\xc9\x84\xb9\xbb\xd9\xc8\xf9\xae\x8a\xd6\x9b\xfa\xbb\x03\x1b\x26\xd0\x16\x4b\xbb\x04\xe3\x20\x76\x86\x0f\xf8\x8e\xb8\x1a\x77\x6c\xf5\xd2\x1a\x37\x02\x10\xdf\xd2\x00\x9b\xf8\x2a\xaa\x87\x66\x72\xd5\x76\x36\x89\x74\xae\x9c\xcb\xe6\x1c\x6f\xad\x90\xc6\xaa\x05\x16\x2e\x36\x5a\xbe\xac\x65\x46\xd4\xf9\x96\x6c\xc3\xca\x81\xdf\x6e\x8e\xc6\x0d\xe8\x24\xa4\xa0\xbe\x04\x12\xe0\xb2\xdd\xa2\x5a\x64\x98\xfd\x98\x5b\x60\xe6\xa3\x4f\xec\x2e\x08\x22\x5a\x6e\xb1\x1c\x71\xc9\x81\xee\x69\xaa\x35\x51\xf2\x89\x1e\xaa\x96\x98\x03\xad\x14\xa6\x0c\x0d\x7d\x06\xce\xe0\x02\x72\x44\x73\x2b\x8f\x4b\xfb\x54\xed\x58\x3a\x0f\xe9\x5e\xf9\x90\xa5\xfe\xc1\xac\x76\x5d\x25\x29\xd1\xa5\xcb\x51\xd0\x98\x55\x90\xfc\x59\x07\x50\x44\xe1\xfc\xf3\x34\xfe\x67\xa8\xef\xd0\xd5\xb7\xc9\xae\x5c\x23\x80\x01\x33\x8e\x42\x7c\xd6\x13\x7f\x52\xe9\x58\xd7\xd7\xff\x8f\xb9\x2f\xef\x6e\xd5\x48\xfb\xfc\x3f\x9f\x82\xe3\x4c\x4f\xba\x47\x61\x29\x76\x7c\xef\xcd\x34\x12\xda\xd1\xbe\x6b\xce\x9c\x3e\xec\x20\xb1\x09\x10\x08\xf9\xf5\x77\x7f\x4f\x15\x92\x2d\xdb\xf2\x4d\xd2\xc9\xdb\x27\x4e\xae\x05\xb5\x3c\xfb\xf3\xab\xa2\x6c\xfc\xe4\x81\xb8\x9e\x4d\x24\x0a\xfd\xcd\x23\x2a\x6e\x09\x06\x25\x46\xec\xf8\x4f\x3e\x14\x28\x82\xcf\x70\xe5\xe1\x06\x58\xd2\xdc\xa9\x9d\x02\xff\x8b\xe1\x6a\x49\x6a\x65\xdf\x8e\x99\x2d\xfe\xfc\x37\xa6\x91\xe6\x0e\xaa\x18\xab\x6a\xa5\x95\xfc\x8b\xfe\x09\x3b\x05\x7e\x98\x7e\xfb\xc9\xcd\xb2\xf8\x91\x24\x8b\xa2\x20\x0a\x86\x88\x12\x87\xa4\x29\x8a\x82\x64\x7e\xc2\x72\xcf\x2a\xea\xd1\xe9\xdb\x4f\x14\x46\x61\x02\x8d\x01\x8a\x7a\x29\xf7\x5a\xfa\xd6\xaf\x95\xa5\x05\xbf\xad\x2c\x2d\xc3\x13\x74\x55\x94\x16\x50\xa0\xaa\x48\x7b\x69\x82\x57\x04\x45\x71\x7f\x7a\x39\x5a\x8b\x36\x4c\x8b\xbd\x5f\x0f\xf5\x4e\x79\x56\x8b\x32\xb4\xcf\xca\xbf\x32\x80\xf9\x58\xfe\x55\x37\x28\xd3\xbc\x3f\x9e\x65\xef\x94\x8b\xa5\x75\x60\x7e\x22\x0e\x27\x7c\x2c\xcf\x6a\x08\x92\x69\x7c\x52\x5e\x96\x97\x3e\x56\xd3\xd5\x35\x91\xd5\x3f\x2b\x2f\x0b\x3e\x96\xbb\xd5\x74\x5e\xd4\x3e\x19\x2f\x31\xec\xc7\x0a\xb0\x06\xcb\x49\xe2\xff\x78\xb9\xd8\xa5\x24\x75\x08\x7a\x09\x5c\x96\xbb\x5f\x33\x16\xfc\x6a\xcd\xd8\x8f\x24\x7e\x6f\xe1\xd8\xf7\xf4\x25\x02\x60\x12\x20\x80\xca\x12\x02\x26\xd0\x04\xe7\x32\x84\xe4\xd3\x84\x88\x01\x1a\xd5\x53\x67\x71\x78\xe1\xb2\x04\xe7\x33\x04\x83\x01\x06\xa3\x09\x09\x07\x8c\xcb\x10\xa2\x8f\xb3\x04\x8f\x01\x91\xe0\x5d\x9c\x55\x81\x80\x09\x02\x41\xfb\x38\x43\x08\x18\x60\x08\xa9\x23\x11\xe0\x1c\xd0\x34\x01\x30\x6a\x89\x68\x73\x84\xe0\xa3\x8a\xe3\x34\x21\x5c\x69\x0b\xb0\x35\xaf\x88\x30\x04\xb7\x14\x78\x82\xbd\xd0\x60\x09\x01\xb6\x09\xe8\x16\x87\xb7\xf9\xb5\x8d\x47\xe5\xc4\x05\x8c\xf2\x71\x1e\xf6\xc1\xe9\x2c\x01\x7c\x16\x4a\xce\x10\x22\xc6\x56\x05\xe3\x45\x97\x55\x79\x1a\xa9\xe8\xe2\x2c\xf1\x5a\xad\xf7\x6f\x34\x63\xdb\xf6\xaf\xd6\xa6\xa6\x7f\x1b\x08\x00\xf1\x0a\x02\x1c\x45\x50\x34\x53\xe1\xc0\xa5\x95\x7e\x6d\xfd\x43\x40\x50\x61\xc9\xfb\x78\xe4\x19\x56\xba\x5f\x3a\xfa\x63\xf0\x0a\x14\x60\x78\xfd\xbb\xc1\xfb\xa9\x25\x98\xdf\x68\x09\x40\x70\x00\x5c\x6c\x01\x08\x01\x5c\xaa\x74\xf3\x1c\x41\xa3\x76\xfa\xb5\xfd\xaf\x6f\x8d\x97\x3c\xe1\x59\x82\xc1\x38\x8e\xe0\x8c\x6b\x65\x7e\x54\x6f\x9e\xc1\x39\x02\xc0\x0f\x81\x60\x50\x25\x77\x94\x23\x30\xf4\x44\x94\x3d\xc2\x8c\x96\x08\x1e\xe3\x19\x82\xc7\x68\xd8\xc7\xb3\x06\x9c\x49\xd0\xd5\x0c\x1e\x17\x09\x0e\xa7\x51\xad\xfc\xaa\x24\xbb\x08\x93\x00\x07\x38\x07\xb9\xf0\xe8\x03\xd1\x83\x5c\xe1\x38\x20\x10\x55\x8d\x79\x8c\xae\x6a\xe3\x57\x79\x74\xa9\x12\x0f\xaa\x82\xf4\x04\x8f\xc1\x1c\x10\x08\x50\xa5\x22\x2a\xeb\x4f\x53\x38\x20\x38\x8c\xaf\x8a\xb9\xc3\x1c\x64\x71\x54\xbb\x5d\x42\x17\x3c\x22\x44\xd0\x18\x4f\x48\xa8\x4e\x3d\x45\x30\x18\x15\xe0\x12\x21\x61\x80\x23\x18\x83\xe0\xaa\xf2\xf5\x50\x5f\x0c\x55\x9b\xa7\x91\x19\x84\x4a\x7d\x48\x16\x10\x34\xce\xa3\x66\x00\x08\x09\xe2\x84\x80\xd1\xa8\x40\x3c\x8b\x11\x2c\x26\x10\x22\x9c\x4a\x63\x2c\x92\x40\x40\x2a\x71\x50\x12\x1e\xa7\x09\x21\xa0\x21\x1e\x00\x17\x10\xc0\x80\xa2\xb0\xa8\xde\x3c\x5d\x55\x9d\xc7\x51\xcd\x7e\x1e\x07\x30\xc1\xf1\x97\x4a\xf5\x0c\x92\xc3\x05\x04\xb7\x64\xc4\xaa\x32\x3d\x85\xa1\x0a\xfb\x17\x2d\x08\xe1\x1c\xb0\x18\x85\xa4\x87\x73\xa9\xca\x4a\xc8\x79\xb7\xf4\xd1\xdc\x1c\x0d\x87\xc2\x73\x04\xe3\x12\x92\xf1\x61\x18\x0e\x90\x64\xd0\x27\xa8\xa0\x3f\xb2\x24\x14\x04\x87\x1a\x1a\x84\x40\xd0\xd0\x3b\x50\x3a\x68\xae\x4b\xdd\x7d\x74\x53\x79\x89\x47\x4e\xa8\xa6\x30\xe8\x0e\x40\x89\xf9\xaa\x12\x3f\x5b\x89\x4c\x70\x44\x35\xe5\x52\xea\x1f\xfd\xcf\xc3\x48\xa9\xc8\x48\x50\x17\x18\x33\xb0\x57\x22\x58\x48\x0b\xca\x2c\x22\x81\x51\x49\x7f\x24\x1f\x83\x51\x97\x9a\xff\x00\x46\x56\x25\x2f\x0e\x85\x84\xda\x5e\x03\x01\xa1\xb4\x08\x83\x8f\x35\xa0\xba\x4c\xe5\x66\x64\x2a\x89\x80\xfe\xe4\x2b\x8d\x3e\x15\x85\xa9\x9c\x05\x09\x23\xb5\x38\x8c\x86\xb2\x20\x93\x5f\xdc\x70\x1d\x22\xc2\x69\xa8\x11\x9a\xc3\xc5\x09\xa9\xe2\x59\x89\xcd\xe0\x28\x80\x01\x42\x77\x68\x6c\xd1\xc0\x61\x9c\x13\x00\x47\x63\x68\x9c\x43\x76\x85\x5a\xc1\x85\x84\x82\x31\x05\x6f\x40\x15\xf9\xb0\x85\x21\x78\x02\x60\x1c\x8c\xb5\x01\x03\x07\xb1\x80\xe0\x0d\x82\x23\x68\xc4\x82\xbe\x9a\xf8\x62\xa8\x4a\x3c\x68\x6c\xe4\x0d\x09\x0a\x47\x57\xce\x82\x46\x82\x9e\x85\x6e\xcb\x01\x0c\x07\x09\x0d\xa6\xab\x39\x48\x89\x57\x7b\x22\x54\x40\xc2\x72\x17\xfb\x82\x2a\x2f\xcf\x01\xce\x11\x0c\x94\x01\x5a\x06\x5a\x95\x87\xe9\x08\x93\x13\x86\x64\xe5\x66\xee\x85\x18\x8e\xfc\x42\xbf\x50\x43\x7e\x23\x24\xd4\x5a\x19\x58\x80\x06\xee\x00\xc1\x40\x1d\x95\x1f\x5e\xc7\xb3\x88\x2f\x5d\x91\x61\xa0\xf7\x10\x65\xec\x8a\x11\x28\x6b\x58\x0c\x18\x04\xc0\x58\xe8\x20\x4c\x42\xde\x65\x21\x52\x08\x98\x88\xc1\xb1\x50\x78\xb8\x48\x03\x89\xa0\x71\x16\x4a\xc7\xe1\x0c\x21\x11\x00\x17\xa1\x84\x02\xcc\x54\x94\xeb\x15\xda\x41\xd3\xa2\x3c\x81\x68\xc1\x9c\x03\x38\x41\x7c\x49\x64\xae\xf2\x36\x8d\x51\x50\x42\x98\x69\x9c\x51\x69\xff\x6a\x0b\x64\x24\x04\x11\x06\x1c\x88\x21\xc9\xd9\x2a\xd9\x10\x47\x44\x05\xba\x16\x47\x84\xaa\x68\x62\xa1\x49\x61\x1e\x40\xe3\x57\x1f\x1c\x0a\xa3\x4b\x38\x54\x99\x07\xd9\x70\x88\x0d\x4b\xb0\x18\x82\x4f\x48\x0e\x4a\x00\x7d\x2c\x61\x08\x26\x09\xa8\x2f\xc2\x23\x88\x57\xd7\xa0\x15\x70\x16\x05\x22\x54\x5c\xac\xa0\x98\x41\xb8\x45\x13\x0c\x8e\x60\x9b\xab\x92\x50\x22\x44\x08\xf2\x30\x0b\x61\x08\x42\x11\x6f\xe4\xc4\x5f\xf4\x15\x2e\x21\x0e\x71\xb3\xd2\x89\x25\xa4\x80\x65\x11\x00\xd3\x95\xcd\x98\x2b\xea\x80\x6b\x9a\xbc\x82\x13\xd4\x89\xcd\x21\xd0\x41\x6d\x2a\x72\x10\x52\xa8\x1c\xd9\x15\x47\xac\x2b\x63\x43\xad\xe9\x73\x20\x20\x2c\x60\x5d\x48\x03\xb6\x55\x30\x49\x80\x2a\x18\x51\x40\x72\x08\xf5\x70\x00\xe9\xde\x88\xc0\x5e\xc3\x1a\x7d\x7c\x80\x1c\xe8\x3b\x48\xe7\x02\x0f\x55\x78\x09\x50\xe9\x8b\x66\xd2\x15\x30\x38\x44\x4a\xc4\xaf\x14\x91\x69\xf9\x2a\xae\x2b\xc8\x60\x31\xc8\x9c\xab\x10\x94\xaf\x72\x82\xf9\xee\x74\xb1\x9a\xce\x9e\x07\x80\xc3\x38\xc1\xb8\x75\xbe\x80\x92\x01\xba\x0f\xc9\x8c\x82\x14\x99\x9d\x41\xc8\x82\x16\x10\xa3\xf2\x09\x0b\x09\xa1\x00\x91\x90\x29\x20\xbc\x21\x5c\x40\x9c\xaa\xe8\x15\xab\x19\x95\xa8\x70\x81\x35\xc0\x75\xac\x78\x19\x2b\xbd\x40\x19\x7b\x03\x65\xaf\x38\x8f\x7c\x26\x18\x57\xa0\x67\x5e\x60\x47\x44\x1e\xc3\x90\xd8\x7c\xb5\xc2\x31\xf0\x1e\x86\xfd\xd5\xd6\x03\xc0\x63\x3c\x05\xc1\xf0\x92\x0d\x34\x8e\x10\x06\xf2\x85\x61\x5b\xad\xfa\xd8\xcb\xaa\x08\xaa\x2d\x82\x81\x3c\x4c\x80\x0b\x6c\x31\x50\x8f\x57\xf8\x82\xda\x5d\xd6\x27\x84\xe2\x90\x7f\xa5\x0a\x21\x5e\x51\x0f\x2e\x4d\xe2\x1b\xf0\x40\x2b\xca\xb5\x0d\xe6\x22\x8a\x94\xcb\xd2\x82\x62\x4e\xba\x48\x08\x30\x44\x0d\x86\xe0\x00\x48\x18\x4f\x57\xe1\x07\xd9\xa1\x25\x89\xaf\xdc\x59\x39\x19\x5c\x56\x9c\x0a\xa3\x2f\x6a\xc0\x64\x82\x19\xc1\x5c\x81\x8e\xc1\x2f\x8b\xd0\x75\xc1\x46\x3e\xbc\x80\xf2\xc5\xdc\x77\x1f\xad\x98\xd7\x47\xab\x4f\x37\xb8\xec\x6f\xdb\xe0\xc2\x27\x32\x5e\xaa\x36\xb8\x02\x4b\xd0\xd4\x65\x83\xcb\x89\x84\x80\xda\xe9\x6f\x3f\x89\x02\x21\x50\x7f\x74\x83\xfb\xf1\xb9\xdf\x96\x2c\xdb\xe6\x3f\x79\x90\x17\x3e\x3e\x38\xdb\xa2\x65\xda\xdc\x27\x0f\xe6\xe0\xe3\xee\xd9\x66\x2c\xde\xbe\xbf\x7b\x26\x78\x40\x7f\x3c\x58\x30\x4c\xdd\xd2\x3f\x7b\x90\xff\x38\x9c\x31\x8c\xcf\xce\x21\x04\xee\xce\xb9\x82\xa0\x8b\xe6\x27\xe7\x04\xe2\x9d\x73\x0e\x43\xd3\x80\xf1\xd9\x39\x81\xf0\x71\xff\xaf\x1b\xa2\xa8\x7f\x22\xbe\x44\x7f\x1c\xaf\x59\xbc\xa1\x7d\x36\x9e\xbf\xf3\x30\x62\xb3\xa6\x74\x7f\xfc\x9f\x79\xae\xe0\xe2\xb4\xb0\x04\xf7\xe3\x9e\xfd\xd5\x23\x85\x37\xb3\x7f\xef\x69\xc2\xb5\x01\x4a\xbb\x8b\xbc\xf0\xdb\x4f\xba\x95\x5b\xfe\x8b\x16\x69\xee\xfc\x8d\x69\x3e\xfc\x91\x63\xc3\x93\xff\x17\x7b\x1f\x29\x78\x53\x1e\x3e\x69\x35\x9b\x13\x32\xd0\x82\x2d\xb3\xa1\x6b\xd4\xb9\xdb\xa0\x07\x41\x77\xde\xdc\x2f\x36\x4e\x73\xda\x9a\x34\x93\x13\xd7\x14\xfb\x73\x0f\xe8\xa4\x2b\x48\x32\xc9\xce\x56\x4c\xd8\x18\x5a\x1b\xc7\xa9\x6f\xb6\xcb\xe6\x60\x41\x96\xcc\x90\xd9\x0a\x03\x61\x34\x57\xc8\x36\xef\xef\xe9\xe4\x58\xd0\xd4\x79\x6a\x2e\xc8\xf5\x52\x02\xcb\x65\x9b\x0a\x66\x93\x3e\xc9\x84\x40\x23\x77\xfb\x92\x37\xf9\x75\xca\xb4\xc5\xd5\x7a\x56\x1b\x17\xdc\x90\x57\xd7\x3b\x55\x6d\x1f\x43\x8d\x14\xc4\x68\xdb\xb7\x92\x76\xba\xe9\x67\x89\xd2\x04\xfc\xb1\xd7\x56\x81\x2a\x39\xcd\xd1\xc8\xd8\x98\xb4\xa9\x02\x7b\x58\x24\xba\x4a\x92\xda\x7a\x28\xf4\x80\x65\x8f\x07\xc1\x7e\x71\x68\xb6\xe4\x3d\x25\x53\xcb\xed\x50\x6f\x35\xb5\x49\xa3\x9e\x1a\xdd\xfd\x7a\x27\x09\x5c\xc9\x0c\xd5\x83\x74\x2a\x2d\x71\x5c\xdf\xcb\xa1\xd7\x19\xb5\x62\xb7\xb6\xa3\xad\x06\x9b\xa4\x66\x54\x67\xd5\xb4\x75\xd4\xdb\x3e\xd9\x39\x88\xd3\x2c\xdf\xac\xe2\xd3\x7c\xe2\x71\x74\x04\x76\xf9\xca\x6b\x6f\xb4\xe9\x56\xa5\x48\xed\xa8\x38\xa3\x7d\x83\xdc\x8a\xf5\x8d\x4a\x8f\x0f\x27\xcf\x8c\x41\x6b\xbb\x77\x23\xe5\x14\x5b\xda\x5a\x26\x17\xbb\xe3\x8e\x64\x3b\xd1\xe8\xd4\xef\xef\xbc\x91\x67\xed\x85\xe9\x62\xe6\x4e\x87\x93\x95\x36\xdc\xb4\x26\xc7\x81\x66\x27\x9b\xc6\xc9\x2b\xd8\xe8\xbc\xed\xdb\x07\x7d\xd3\xa3\x9a\xf9\xd4\xf4\x81\x32\x29\xcb\x79\x2a\xae\x1b\xc3\xb9\xcc\x2f\x9a\xea\xa0\xc8\x95\x52\x8d\xb7\xab\xee\x76\x38\xf4\x87\xaa\x3f\x19\xf5\x69\x75\xd0\x9b\xf6\x6a\x9c\xbc\x3f\x6e\xc1\x4c\x68\xb4\x5a\xe7\xde\x79\xcf\xf1\xed\x70\xb1\x9b\xac\xfc\xcd\xfe\xd0\x88\xea\xab\x96\x1e\x85\xcd\xe5\xc6\x50\x55\x99\x35\x87\x61\x9d\xa7\xd9\xf6\x24\x55\xea\xab\xae\x63\x6f\x7b\x4d\xe7\xb4\x8f\x1a\xee\x79\xd6\x5a\xe5\x21\xbb\x8c\x27\x56\xa0\x04\xf4\xb2\x58\x4f\xd2\x75\xaf\x68\x01\x97\x37\x6a\xce\xc9\x9f\x70\x3b\x67\xe6\x35\x17\xcd\x8c\x2a\xcc\xae\x25\x64\x83\xe6\xac\x16\x36\xdb\xb4\xd6\x50\xbd\xde\x60\xd4\xed\xae\xba\x89\x64\x51\x4a\xb3\xa9\xca\x83\x45\x52\x4c\x8f\x86\xbb\x94\xcb\x79\xdf\x0b\x16\xc5\x48\xe0\x7a\x01\xbf\x6c\x31\xf5\x5c\xf0\x82\x91\xb6\xab\x9d\x4c\x61\xd1\xea\x2f\x67\x64\x7d\xdc\x6b\x01\x9d\x6c\xb2\x99\x33\x4f\x9a\xac\xd4\xe3\xa9\x11\xb7\x37\xac\x68\x78\x88\x0a\xef\x78\xdc\xf4\x35\xd1\x71\x3b\x6b\x99\x15\x17\xd2\x60\x4e\xcb\x13\xa7\x9c\xe6\xf3\xb9\xdb\x64\x28\x7d\xe2\x69\xb3\xb6\xc6\x96\xea\xa0\x37\x6c\x45\x35\xe5\x40\xd2\x46\x27\x63\x1b\x1b\xbf\x28\x5b\x36\x3d\xe3\xeb\x9d\xa2\x48\x06\x05\xa9\xe5\x8a\x3e\xe5\x1a\x60\x2f\xb8\x60\x33\x61\xfb\x1d\x46\x0e\xec\x9a\x6c\x6c\xcb\xa6\xbe\x1d\xe7\x52\xa3\x9b\x9d\x27\x0a\xf0\xa5\xa6\x9e\x6d\x46\xbb\x5c\x60\x73\xd2\x64\x46\xd2\x74\x30\x9e\x2b\x49\xda\x2c\xda\xdd\xd5\x50\x3c\xd0\xe5\x5e\x58\x0f\x37\xd3\x54\xea\x25\xd3\x9c\x59\xb2\x72\x5d\x56\x66\xed\x29\x6f\x4d\x28\x72\x38\xf9\x33\x7f\x64\x79\xf2\xd3\xd3\x5f\x0c\x24\xfc\xdb\xbf\x5a\x78\x68\x35\x9b\x8b\xf1\x72\x6d\x8e\x37\xe4\xd1\x5a\x6d\xbb\x91\xb7\xd9\x7a\xb3\x4d\x7f\xe3\xf6\x0c\xbe\xa9\x9b\xc7\xce\xc8\x75\xbc\x5d\xc4\x64\x64\xd1\x01\x67\xbe\x4e\xf5\x64\x77\x54\x0e\xba\xaa\x7b\x8a\xd8\x7d\xaf\xbd\x07\xf2\x6c\x2e\x9f\x8a\x55\x8b\x1a\xc4\x31\x67\x76\x0c\x29\x6f\x2d\xce\x9b\xc2\x33\xb5\xe8\x10\x1c\x6a\xa2\xc4\x49\xa7\xb3\x7e\x6e\x67\x43\xe3\xc4\x4b\xe3\xf9\x8c\xe6\x9b\xf3\x60\x92\xcd\xa4\x84\xed\x94\xe4\x29\x17\x06\x2b\x61\xb7\xac\x65\x2e\x57\x9e\x97\x86\xb6\x19\xaf\xc9\x5a\xad\x9b\x49\x47\x76\x28\xe7\xb5\xc6\x72\xca\x67\xf5\xc5\x62\x7e\x18\xf4\x52\xc5\x98\x9e\x77\xdb\xd1\x76\x20\xae\xa4\xad\xda\x3f\xd5\xc8\xb5\xa2\xb3\x16\x47\xee\x3b\x5c\x37\xa4\xfc\xb8\xbb\x59\xb5\x17\x5a\x83\xda\xcc\xb7\x61\xbd\x21\x37\xfb\xd1\x72\xca\xa8\x0c\x1f\x29\x91\x30\xd4\x53\xc7\xdf\x16\xfa\x41\xe1\xbd\x49\x7f\xb4\x6e\x0d\x8c\xfe\x62\x69\xd7\xf7\x75\x39\x9a\xb8\xbe\xc2\x9d\x4e\x03\x25\x26\x3b\xc9\x2c\x67\x0e\xa0\xe7\x6c\x56\xcc\x99\x3a\x51\xfd\xf5\x79\xdf\xd8\xf4\xb4\xe9\xd6\xdf\x25\x47\x9a\xd1\x3a\xab\xf9\x59\xf5\xb4\x40\x2e\xcb\x2c\xa7\x46\xd2\x62\x63\xda\xdc\x58\x4e\x0e\x7e\x1c\xd7\xed\xc1\xc2\x3e\xb2\x91\xac\x36\x93\xc3\xb6\xde\x37\x16\xa7\x41\x6b\xda\xe8\x34\x63\x4a\x71\x56\x9c\x1a\xb1\x43\x69\xd8\x1d\x02\xb3\x45\xad\xd7\xe9\xb2\x35\x5a\x94\xe3\xde\xfc\x1c\xd5\x56\x75\x79\xa8\x78\xe6\x2e\x16\x33\xa7\xd3\x6e\x33\x06\xa5\x84\x3d\xf6\xd8\x9d\xda\xac\x31\x6a\xd4\xb5\x15\xd7\xdf\x6d\xc4\xd3\x7e\xab\x0a\xf4\x29\xee\x49\x13\xa3\x75\xe6\xf4\xe5\xa1\xb3\xe8\xb5\x3b\x5b\x95\xde\x64\xc3\xa0\xef\x51\xfc\xa6\x51\x7a\xcb\x96\xce\xa6\x64\xde\xec\x0f\xe6\xb2\x0d\x62\xd6\x32\x47\x6d\x3e\x18\x78\xe0\x3c\xe5\x8b\x66\x6c\x2e\x8a\x75\x2d\x57\x95\x6c\xdf\x38\x77\xa2\xbe\x10\x67\xc6\x80\xd7\x4a\x35\x68\x6b\xbb\x3c\xb3\x4e\xec\xd8\xf7\xca\xa8\xbb\x6f\x4d\x77\xc1\xa2\x29\xcf\x2c\xbf\x4e\x27\xeb\xc9\x74\x66\xef\x16\x8d\xb9\x34\xf6\x57\x71\xb0\xa2\x81\x37\x6f\x9f\x1b\x72\xd9\xdc\x2f\xbc\xd3\x78\x7a\x58\xbb\x16\xbd\x64\xcf\x7d\xe3\xac\x9b\x41\xa9\x3b\xfb\xb8\x47\x19\xed\xd1\x51\xe6\x37\xf4\x60\xde\x48\xfb\x91\xc7\x75\xd2\x61\x5f\x18\x32\x83\x61\xed\x58\x6c\xb4\x95\x7e\xda\xd8\x91\xaa\xee\xcf\xe6\xc9\xb0\x0a\xde\x4f\x36\x2b\x6d\xeb\x06\xe2\xb8\xd3\x69\x33\x67\xdb\x8e\xc1\xa2\xe8\xcd\x3a\x67\x29\xcf\xf7\x0b\x71\x1c\x99\xba\x31\xd9\x6c\x36\x33\xce\x3f\x6d\xf6\xa7\xf9\xbe\x6d\x2e\x95\x89\xb9\x04\xbd\x14\x1c\xc6\xce\x46\xe1\x7b\xdd\x63\xb7\x29\x38\xe9\x7a\x69\xd9\x5d\xb7\x7b\x1c\x50\xdc\x5e\x30\x8b\x81\x6e\x0d\x02\x57\x14\x34\x20\x1e\xed\xee\x40\x5b\x6e\xca\x38\x49\x7a\xaa\xb3\xb3\xe8\x61\x52\x03\xd9\x79\xb3\x96\x87\xa1\x12\x26\xcc\x79\xea\x76\x76\x8c\xb0\xcc\x4b\xba\x88\xd7\x9d\x6c\x28\x9b\x1c\x59\x4c\x36\xb2\xc2\xaf\x06\xc7\x39\xdd\x28\xa2\xe5\x9f\x0a\x10\xc1\x5f\xec\x45\x24\xcf\xbf\xa9\xb1\x5b\xfd\x79\xa2\x93\x5b\x73\x98\x15\x9d\x81\x36\x95\x36\x0f\x65\x77\x56\x86\x8b\x56\x2f\x9d\x8d\x66\xee\xb0\x68\x68\x81\xb7\xd9\x36\x15\x46\x75\xba\x7b\xe3\x78\x8a\x86\xa4\xd7\xd8\x5a\xe3\xad\xb7\x69\x2b\xb4\xd6\x56\x6a\x1e\xd5\xe2\xfa\x83\x86\x7b\xf2\x97\x9a\xb6\x97\xfb\x74\xb9\x37\xe4\xac\xb6\x3a\x9b\xea\x51\x38\xef\x4f\x11\xb3\xda\xaa\x6c\x7c\x14\x83\xb5\x1d\x58\xd6\x86\x11\x45\xee\xe8\xf0\x42\x12\x8d\x5b\x2e\x17\xe6\x06\x4f\x07\x92\xbb\x8b\xa6\x35\x4e\x1d\xc4\xc2\x20\xd9\x6f\x6c\x46\xa0\x0e\xcb\xcc\x88\x6a\xcb\xac\xb1\x68\xc5\xfa\xae\xb6\x6b\x4f\x6b\x3d\x7d\x15\x0a\xfc\xa8\x9c\x88\xd6\xb8\x48\xb7\xf2\x7c\xa2\x8b\x53\xd2\xd5\xc2\xad\xd3\x1d\x3a\x3b\xa9\x7b\xb0\x8e\xf5\x56\xa3\x00\xfd\x4c\x1a\x0d\xea\xe1\x70\xd5\x48\x69\x76\x5d\xec\xdb\xe4\xa4\xbf\x59\x34\xbd\xf6\x6e\x29\x8f\x27\x91\x4d\x26\x07\x4a\x10\x99\x78\xe6\x36\xe7\xcc\x42\x9d\x44\xe2\xe9\x4c\x79\x33\xae\xa5\xc9\xc3\x20\xe9\x4c\x3a\xb4\x12\x1d\x36\x35\x65\xa6\xce\xce\xfc\xf4\x6c\x19\x2b\x3f\x54\xa4\x32\x58\xb0\x82\xba\xd9\x99\xec\x88\xab\xaf\x0f\xca\xbc\xcd\xb6\x06\xcc\x30\x9e\x37\xf7\xb1\xd9\xe3\x92\x82\x92\xa3\x42\x9d\x0e\x74\x77\x61\xc7\x9c\xe8\xcc\x47\x9a\x42\x2e\x3a\xc1\x70\x32\xee\xf2\x9b\x20\xef\xaf\xa6\x6b\x70\x6e\xce\x3a\x8b\x1e\x19\xd5\x53\x3a\x0c\xc6\x5a\x6d\xe0\x14\xd4\xb6\x3b\x60\xb2\x6d\xd9\x8e\x7a\x45\xe9\x9c\x27\xc3\x3a\xbd\x1b\x96\xbd\xee\x76\x2d\x78\x75\xca\x8f\xc7\xd1\x40\xa0\x16\xed\x60\xbc\x16\xcf\x8d\x45\x2d\x69\x8b\x43\x65\x79\xea\x14\xa6\xd7\xe0\x82\x7e\x3a\x5e\xb4\x16\x43\xd2\xc9\x33\x55\xb5\x19\x29\x6d\x9d\x97\x07\x6d\xc8\x6c\x92\x06\x3f\xdf\xd5\xb5\xe3\xc1\x5d\xbb\x43\x19\xcc\x27\xd1\xc1\x8f\x96\x82\xa2\xd5\xe2\xdd\xf6\x00\x5a\xe9\x7a\xd1\xd0\x82\x16\x2d\xed\x78\x35\xdf\xb8\x36\xe3\x75\x67\x70\x33\xd9\xca\x25\x65\x6b\xe5\xd1\xd1\x9d\x9e\xcf\x63\x7b\xd4\xae\x31\x6e\x2c\x4b\x0b\x69\x51\x7a\xd1\xc8\x9f\xf7\x84\xb8\x65\xcd\x1b\x93\x19\x3f\x6d\x9f\xbb\x96\x5e\xda\xb5\xe8\xcc\xc5\xb3\xf3\x2a\x0b\x66\x2b\xd0\x1c\x49\xb1\x9b\x4f\x28\x2a\xf5\xeb\xd3\x8c\x14\x0f\x53\x46\x89\x56\xe6\x5a\xf7\x8c\xf3\xc2\x9b\x9f\x4d\x8e\x56\x6a\x99\xa9\x06\xe5\xbc\x0e\xd8\xe0\x04\x92\x81\xdc\x5f\x1a\xd3\xb8\x29\xcf\x77\x49\x7a\x6c\xfa\x96\x45\x76\xd6\xed\x20\x6c\x4d\xcb\xfa\xa8\xad\x30\x54\x83\x0c\x9b\xca\x6e\xe8\xa4\x42\x43\x89\xd3\x4d\x10\x76\xda\xcc\x66\x6c\x39\xf5\x46\xde\x49\xa5\x68\x63\x07\x62\xd8\x96\xcc\x9e\xc6\xad\xd9\xbe\x28\xcb\x93\xf3\x64\xcd\xf6\x67\x43\xa6\x30\xfe\xd4\x97\x0a\xcb\xbf\x5a\x2e\x9b\xa7\xd7\x1a\xa3\xfe\xa5\x2e\x8a\x3e\x10\x02\x6e\x43\x6d\xe3\xec\x48\x03\xb9\x58\x15\xee\x26\xb6\x67\x4a\xcb\xad\xed\xf3\x7c\x6a\x8a\x43\xaa\x63\xb3\x5d\xf2\xb4\x32\x6d\x72\x02\x38\xb1\x45\x4d\xa2\x49\xad\xb1\x4c\x5b\x7d\x4d\x9d\x4d\xe2\x8c\x34\xe3\x20\x3f\x67\xf3\xd1\xf9\xbc\x2f\x79\xc3\xca\x46\xf1\xca\xd8\x6e\x73\x7d\xc4\x0c\x46\x1c\x07\xd8\xd9\xe9\xdc\x5c\x30\x09\x27\x90\x4c\x3b\x5e\xf9\xfe\x80\xcc\xc6\x6c\xaa\x32\x73\x2d\x99\x8e\xd6\xc7\x59\x44\xce\x56\xbd\x7c\x2d\x80\xc5\x51\xa4\x1a\xb6\xeb\x27\xe4\x9c\x5d\x98\xab\x96\xbc\xb4\xcd\x30\x48\xe7\x8b\x2c\x37\xc7\x0c\x37\x5a\x94\x93\xfe\x32\xec\x39\x6b\xa5\x3e\x37\x76\x92\x67\xc8\xe9\xdc\x52\xb5\x93\xb0\x23\x29\x8e\x3e\x0c\x44\xb0\xd8\x15\x2b\x30\xe9\xad\x9b\xee\xa0\x45\x1d\x36\xe1\x50\xa2\x6c\x33\xcc\xcd\xc8\xd9\x04\x79\x6f\xbc\xa0\xc8\x65\x5d\x8e\x15\xd6\x35\x94\x64\x35\x35\x4a\x6f\x6f\xd7\x81\x90\x26\x67\x67\x25\xe8\xd2\xd4\x05\x79\x33\x3f\x29\x7e\x97\xcd\x96\x65\xa6\xd5\x67\xcd\x66\x16\xac\x5c\xea\x94\x2e\x06\x45\x5c\x84\xab\xdd\x41\xf6\x8d\x53\xe4\x78\x1d\x13\x14\xde\xa4\x6c\x1c\x45\xc1\xeb\x92\xb5\xb4\x97\xd9\x7c\x6d\xb8\x4e\x9d\xd8\x14\x5a\xab\xc6\xa0\xce\x51\xfd\x7c\xbf\x19\xb4\x07\xba\x6a\x6e\x1d\xd5\xb7\x77\xb5\xbe\xd4\x67\x6b\xad\xb0\x35\xa1\x4f\xc2\x2a\xcc\xba\x29\x47\xc9\x7a\xe0\xb5\x0b\xb5\xab\x66\xb5\x7d\xad\x99\x9f\xf3\xd9\xb0\xdb\x39\x9b\x9e\x63\xf6\x48\x39\x58\x4f\xa6\xae\xd7\xc9\xb9\xf1\x68\x56\x6c\x82\x76\xcd\x38\x8c\x97\x11\xd5\x39\x28\xa7\x9d\x78\x9c\xf7\xe9\x3c\x04\x1d\x5b\xab\xf5\x02\xb3\xbb\xcf\xb3\x2d\xc9\xda\xa3\xf1\x7a\xc1\xac\xc6\x4a\xdc\xb2\x86\xab\x65\xb9\xe8\x27\x65\xc3\xeb\xb6\x07\x43\xf6\x9c\x76\x24\xd1\x29\x03\xa6\xd1\x35\x46\xf3\x62\x5e\x5b\x77\xcc\x75\x62\x4e\x26\x1d\x79\x1b\x65\x4d\x71\x5f\x1f\xc7\xb3\xc3\x78\xd8\xc9\xea\xa3\x84\x15\x3b\x8b\x40\x1d\x19\xeb\x69\x6f\x2e\x99\xab\xe1\xa0\xbd\xe9\xb5\xf4\x52\x02\x71\x67\x24\xe7\x5a\xb9\x9f\x69\xdd\xb9\x53\xd3\x0b\xcb\x36\xdd\x24\xb3\x94\xe9\x7c\x30\x2b\xca\xa4\xd5\x70\xba\xa2\xd8\xa4\x38\xbe\x53\xd6\x58\xd9\xa5\x8d\xf5\x64\xab\x32\x53\xb8\xa1\x56\x17\x96\x60\x1f\xd6\xab\xd6\x90\xff\x33\xd7\xcb\xb3\xf7\x17\xab\x27\x18\x48\x2f\xfb\xe9\x3d\x95\xe5\x14\x25\x2f\x5c\xa3\x36\xd8\xf0\xe6\x28\x70\xac\x56\xcf\x01\xad\x68\xb9\x8c\x17\x2b\xbf\xd5\xa0\x52\xba\xdb\x6a\x81\xdd\xa9\xae\xbb\xfd\x1d\x5b\x9f\x9d\x36\x66\x6a\x8c\x37\x46\x33\x98\x04\x5d\xe5\x40\x39\x69\x73\xda\x5d\x7a\x25\x3b\x8f\x15\x61\xd9\x3a\xb7\x40\x27\xe2\x76\x16\xad\xb1\x99\x3b\x3a\x0c\x5d\x3f\xe6\x06\x67\xf6\x7c\x34\xcf\xe7\x98\x2a\xe2\xe9\xbc\x21\xda\xe3\x64\x4f\x91\xf3\x06\x5f\xb3\x95\x6c\xe3\x19\x6a\x47\x12\xe6\xa0\x6f\xd0\xf9\x44\x31\xd2\x5a\xd2\x61\xac\x85\x7c\x5a\x9e\xc3\x90\xb2\x43\xa0\x4c\x07\x62\xb3\xe6\x8d\xcc\x9c\x33\x32\x66\x1d\x6c\xdb\x7c\xb9\xf4\x87\x3b\x3e\x8d\xfc\x85\xee\x2c\xe7\x19\x75\xe0\x5a\xed\x6c\xcd\xe7\xeb\x43\x83\x5f\xee\xfd\x79\xb3\xd6\x97\x47\xe4\x68\xa4\x74\x66\xdd\xc9\x78\x3a\x89\xd3\x75\xa3\xb6\xdf\x37\xcf\x74\x53\x95\xa9\x32\xcd\x72\x91\xcd\xd4\x73\x79\x34\x52\x7d\x55\x2f\xbd\x54\x6e\xdb\xb5\x89\x3c\xa3\x1b\x0d\x65\x3a\x55\x07\xbd\x41\x70\x6a\xd4\x3c\xb1\xc1\xee\x4c\xb5\x11\x90\xe7\x81\x30\x1a\xf5\x5b\xed\x38\x33\x46\x3c\x59\x9f\xc7\x3d\xaa\xb4\x26\x75\x6a\x53\x0b\xec\xfe\xe4\xb8\xdd\xb6\xa9\xdd\xc4\xb1\xa6\xfa\x4a\x5c\x9b\x51\x10\xe9\xa9\xa4\x0e\xc5\xd4\x30\x6a\x8b\x71\x67\x58\xb2\x4a\x71\x10\xbb\xfe\x2e\xca\xba\xdd\x49\x33\xe0\x24\x72\x1a\xcd\xca\x01\x68\xf4\xf7\xeb\xfe\x76\x58\x0f\x84\x7d\x77\xe9\x94\x03\xbe\x70\xe4\x70\xe6\x4c\xfb\x52\x7e\x98\xd8\x9d\xb1\x37\x68\x29\x9d\x43\xd9\x5a\xa6\xea\x54\x6a\x04\x54\xc4\x6e\xce\x91\x2c\xcf\x92\xd9\xae\x61\xf9\x13\x7b\x3a\xd6\xc1\xd2\x60\x0f\x21\xd5\xdc\x70\x2a\xbd\x92\xda\x4d\xad\xae\x1a\xa7\x89\xd3\xea\xc4\x6d\x7d\x3f\xe8\x2a\x3d\x5e\xb2\x6a\xc5\xae\x27\x2e\xd7\x87\xa9\xd3\xf7\x4c\x2a\x11\xec\x6c\x62\x9e\xf6\xd3\x54\x9a\x1d\x64\x7a\xef\xc8\x01\x60\x67\xb3\xee\xc4\x95\x8e\xee\x51\x6d\x8f\x07\x61\xbf\x97\x92\x5c\xff\x70\x54\xc1\x89\x1a\x52\xd3\x46\xea\x9d\x3d\x27\x52\x34\xf5\x50\x37\x3b\xd1\xc0\x2b\xf3\xc4\xaf\xa7\x9d\xe5\x09\x14\xb1\xab\xb0\xf5\x86\x55\x44\x87\x53\xbb\xdf\x57\x0a\xd9\xc9\x46\xa5\xd8\x3b\xda\x9b\xe3\xbe\xc6\x39\x91\xdf\x6e\x6b\xed\x6d\x61\x80\xb4\xdb\x8e\x94\x33\x23\x8f\xc6\xdb\xd9\x52\xd5\x3a\xce\xb2\x28\xcd\xa8\xa7\x0c\x40\x87\x55\xf4\xc9\x48\x39\x3a\x6e\x9d\xd9\xc4\x23\x85\x65\x3b\x76\xd4\x71\xc2\x23\x6b\x09\xb3\x88\x3a\xca\x1e\x95\x66\x1d\xb5\xc7\xc8\x47\x53\xac\x4b\x7a\xdc\x39\xf2\xf9\x38\x9a\x1d\xa5\x79\xa6\xf8\x7c\xb6\x38\x46\x2d\xaf\xbb\x19\x39\x47\xaa\x06\x38\x71\xd0\x0f\x46\xa7\x28\xc8\x4a\x85\x99\x78\x24\x33\x98\x4f\x05\x4f\xec\x53\x4d\xa5\x0d\xda\x9d\x11\xa7\x34\x99\x35\xab\xe4\x43\xcd\xdd\xfa\xbd\x51\xd1\xdc\x8f\xe4\x79\x6e\x8e\x0d\x9a\x24\xdd\x13\x13\xac\x7b\x9c\xdf\xea\x69\x2d\xb1\x2f\xea\xb3\xcc\xa4\x36\x6d\x3b\x1c\xf5\xf4\x41\xdb\x3a\xd1\xe0\xc4\x1b\xa8\x5e\xd1\xc8\xef\x8e\x95\xde\x39\x11\x0c\xf5\xcf\xc1\x09\x3d\x32\x4b\xec\x09\x1d\x5f\x3e\xfe\xc8\xb0\x8c\xc0\xd8\x5f\xec\x28\xcc\x70\x5b\x0b\x3c\xbf\x7c\x7c\xe8\x58\x7e\x6e\x65\x9e\xa1\x61\x43\xeb\x68\x3d\xfc\x8c\xbd\x34\xfc\x8c\xc9\x89\xa7\xf9\x3f\x63\xa9\x16\xa6\x78\x6a\x25\xde\x65\x2a\x62\x00\xd8\xf8\xf4\xc5\xf7\x42\x0b\x77\x2d\xcf\x71\xb3\x47\x40\xb0\xcc\x97\x40\x4b\x1c\x2f\x7c\xa4\xbe\x14\x51\x62\xe2\x7a\x62\x69\xfb\x47\xf4\x1d\xd7\x7c\xff\x0b\x5e\x58\xfa\xde\xcb\xf0\xcc\x3a\x55\x54\x70\xcd\xdc\x1d\xd3\xec\x11\x50\xd4\xdf\xbe\xe0\x41\xfa\x59\xcf\x75\x9e\x16\xe3\xae\xe7\xb8\x3e\x64\x58\x9d\xc9\x3e\x66\x89\x16\xa6\xb1\x96\x58\x61\xf6\xac\xbd\x68\x0a\x80\x60\xe9\xcc\x17\x44\xce\xb4\x8c\x28\xd1\x32\x2f\x0a\x1f\xc3\x28\xb4\x9e\xb5\x47\x37\xca\xad\xe4\x65\x2c\x45\xe9\x94\x25\x7d\x18\x7b\x0c\x4d\x2b\x81\x0a\x3e\x6b\x8f\x9a\x91\x79\xb9\xf5\xb3\xf6\x98\x7b\xa9\x97\x59\xe6\xbb\xb9\xcf\x69\x96\x44\xa1\x83\x3d\x21\xf3\x14\x95\x3d\x04\x8a\x7a\xce\x34\xdd\xb7\xb0\x27\x3d\x4a\x4c\x2b\x81\x02\xfb\x5a\x9c\x42\xe7\x54\x17\x5f\x2e\x1d\x69\xac\x19\x5e\xe8\x3c\x52\x5f\x02\xed\x54\x9d\xda\x56\x8a\xbf\x5e\x56\xa4\x1e\x7d\x2d\xcd\x70\xc3\xf5\x7c\xf3\x85\xaa\x1e\x65\x59\x14\xe0\xbe\x65\x67\x78\xa2\x99\xde\x31\x7d\x64\xe2\xd3\x97\xb7\xbd\x09\xb2\xd8\x6b\xf7\x73\x96\x3c\xda\x5e\xf2\x42\x2c\x7b\xa5\x97\x45\xf1\x23\x05\xfb\xc3\xcc\xc5\x23\x1b\xcf\xca\xd8\xfa\xbb\x95\x5b\xe1\x3f\xde\x2c\x35\x17\x03\xd8\x82\x2d\xda\xda\xf3\xbb\xf9\x20\x3e\x61\x69\xe4\x7b\x26\xf6\xa3\x29\x99\xba\x45\x7f\x89\x35\xd3\x84\x2a\x12\x3c\x67\x05\x5f\x72\x2b\x81\x11\xe6\xe3\x9a\xef\x39\xe1\x63\x16\xc5\xcf\x3f\xc6\x9a\x03\x63\x49\x33\xa1\x6b\x50\x3b\xee\x65\x56\x90\x3e\x1a\x56\x98\x59\xc9\x4d\x84\x3f\xfe\x48\xe9\x8c\xc6\x31\x6f\x75\x7c\x64\x5f\x99\xf2\x92\xc1\x1a\xe6\x97\xab\x8c\xb6\xfd\xc5\xf4\xd2\xd8\xd7\xca\x47\xdb\xb7\x4e\xb7\x51\x4c\x00\xda\x0a\xbe\xdc\xfa\x8d\xa3\xa8\x2f\x30\xf4\x3c\xbb\xc4\x61\x16\x59\x61\xf6\x08\x1d\x64\xe1\xba\x95\x15\x96\x15\xbe\xe8\x42\x61\xc0\x0a\xde\x0a\xfe\x1a\x81\x95\x08\xef\x7a\x2f\x81\xf4\x32\x48\xd2\x4c\xd6\xd4\xdf\x0f\x7a\x1b\x9e\xb6\x6d\xbf\x19\x80\xfb\x91\x13\x61\x4f\x97\xac\xa3\x09\x1a\x1a\xf4\x92\x77\x84\x60\x05\xd8\xeb\x37\xea\x12\x40\x02\x01\xb8\x77\x92\xe2\x81\x15\x1e\xef\xda\xf9\x8d\xa5\xae\x74\xa1\xd7\x30\xea\x0e\x05\xd3\xcb\xb1\xa7\x6b\xd6\x63\x04\x7f\x97\x8d\xe9\xe5\x6f\x22\xf7\x65\x3c\xfc\xef\x93\x39\x69\x0e\xf3\xc9\xf3\xfd\xab\x29\xbf\xbc\xe0\x8c\xf8\xa2\x30\x0a\x36\x02\xd0\xf7\xb5\x4b\x73\xe7\x6a\xcb\x8a\x10\x34\x25\x01\xbb\x90\xc6\x78\xa8\x25\x49\x54\x60\x4f\x57\x8d\x11\x3a\xfc\x78\xf1\xf9\x35\x9e\xef\xc4\xf2\x25\xec\x2e\xd9\x04\x71\xf0\xa2\x10\x0a\x87\xcb\xfc\x97\x50\xfe\x98\x33\x96\x69\x53\x36\xfb\x2e\x7a\x3f\x65\x93\x45\xf1\x67\xc9\x0d\xbb\xde\x67\xf6\x6b\xa6\xc1\x08\x80\x12\x11\x30\x83\x71\xcf\x88\xc2\x9f\x5f\x2f\x7f\xf9\x3f\xd8\xd3\x05\x5d\xaa\xe0\x20\xc2\x08\xfd\x78\x08\xa1\x35\xf6\x54\xb8\x5e\x66\x21\x60\xb2\x1e\xc3\xa8\x48\xb4\xf8\xb2\xe5\x74\xb5\xd4\x7d\x89\x4d\xc1\x16\x59\x09\xbc\x59\x50\x82\x28\x8c\xd0\xb4\xe7\x7f\x06\x96\xe9\x69\x58\x14\xfa\x25\x96\x1a\x89\x65\x85\x98\x16\x9a\xd8\xdf\x5f\x31\x8e\xa3\xa8\xf8\xf4\x0f\xec\xe9\x3b\x3e\xf1\x42\x04\xc1\x37\x23\x0a\xcf\xb4\xde\xf9\xec\xca\x2a\x4e\x3c\xe8\xb8\xb7\x50\x72\xd7\xbb\x97\xde\x9f\x5f\x75\xfa\xf9\xcd\x4a\x49\x51\xd4\x1d\x4f\x7e\xe6\xb0\xdb\xd1\xf7\xe2\x06\xf6\x6b\x77\x57\x0f\xea\x7b\xcb\xce\xff\x73\x13\xcb\xfe\xff\x8f\x9a\x9d\x55\x70\x50\x61\xd1\x03\xf6\xf7\x07\x4c\xcb\xb2\xe4\xef\xb0\xfb\x1f\xd8\xc3\x3f\x1e\x9e\xb3\x04\x7b\x42\x4a\x57\x6b\xad\x17\xa6\x9e\x69\x3d\x6a\x79\xe4\x99\xbf\x15\xc9\x6f\xd7\xd1\xcf\xd1\x1c\x6a\xf2\xfc\x4f\xb8\x52\xe7\x9e\x55\xc4\x51\x92\x5d\xc3\xc8\xb4\x72\xcf\xb8\xfc\xc8\xf1\x99\x30\x71\x08\x1f\xaf\xc6\x87\x77\xcf\x04\xfc\x8e\xc3\x58\xc2\x9e\xd0\xa5\xed\x47\xc5\x63\x15\x5b\xe8\x3e\x75\x13\x2f\xdc\xe3\xe0\xd2\x5d\xdd\x3e\x82\x67\x22\xf0\x71\xed\x98\x45\x57\xe4\x40\xf9\xf0\x08\x5b\x9e\x09\xb4\x2e\xe2\x89\x95\xc6\x51\x98\x22\x6c\xbd\xf2\xd4\xfd\xc8\xd8\xdf\x2c\xa1\x5f\x20\x14\x40\x96\xf8\x09\xcd\x7d\xd9\x56\xbc\xb4\xa7\x46\x12\xf9\x3e\x4c\x9e\x2c\x3a\x1a\xee\xf3\x0f\x5f\x49\xf4\x06\xc2\x2f\x3f\x7c\x0d\xac\x4c\xc3\xae\x2f\x3b\x3c\x1c\x33\x1b\x17\x1f\x30\xf2\xda\x11\x6a\x81\xf5\xed\xc1\xb4\x52\x23\xf1\x62\xe8\xc6\x07\xec\xe2\xae\x6f\x0f\x32\x66\x7a\x89\x65\x64\x51\x52\x62\x91\x8d\xd9\x9e\x6f\xa5\x98\x1b\xa5\x30\x10\xa2\x10\xcb\x5c\x0b\x33\xbd\x34\x4b\x3c\xfd\x98\x59\xe6\xcf\x98\x69\x41\x20\x4e\x34\xdf\x3b\x5b\x26\x56\x58\x3a\x76\x4c\xbd\xd0\xc1\xba\xe3\xd6\xec\xe1\xca\x30\x4e\xa2\xd8\x4a\xb2\xf2\xdb\x43\xe4\x3c\x66\x5e\xe6\x5b\x37\x1c\x5b\x88\x45\x14\x7e\x67\xca\x7d\x51\x9f\x9e\x30\x62\xac\x65\x2e\xf6\xfc\xfc\x09\xa7\x32\xbe\x65\x54\x58\x3a\x0c\xe8\xfb\x63\xd1\xc3\xe7\xcd\x60\x37\xcb\xe2\xf4\x91\x24\x1d\x2d\xb3\x0a\xad\x44\x99\x47\x78\x11\x09\x3f\xc9\x49\x30\x53\xac\x8d\x6c\x49\x81\xa3\xf1\x43\x73\x1e\x9d\xe5\xed\xb1\x6c\xab\xcc\x04\xac\x77\xa9\x9a\xe5\x6b\x5a\x5c\xb7\x4e\xbd\x8e\x18\x8d\x77\x87\x87\xb7\x76\xcf\x0a\x2f\xcb\xac\xe4\x83\x1d\xee\xa9\xf3\x76\xc6\x7f\xd0\x63\x6f\x19\x1b\x5a\x62\xde\x70\x4c\x8f\x41\xa0\x25\xe5\xbf\x7c\x2d\x71\xac\x7f\x55\x96\xbb\x3f\xf1\x3f\x6f\x55\x23\xb1\xb4\x2c\x4a\x6e\x78\xfe\x13\x12\xff\x64\x34\x8a\x87\xef\x0f\xfd\xcf\xa9\x70\xc5\xa8\xdb\x90\x45\xbf\x12\x71\x0b\x56\x3f\x63\x5e\xe8\x65\x9e\xe6\xe3\xa9\xa1\xf9\xd6\x37\x40\x50\x90\x8c\xef\x85\x7b\x2c\xb1\xfc\x6f\x0f\xa9\x1b\x25\x99\x71\xcc\x30\xb8\x6e\x3e\x60\x10\x75\xbf\xdd\xbe\x0a\x75\x42\x0b\xea\xf5\x88\xa5\x3a\x4c\x69\xca\x4d\x74\xa4\xd2\x94\xbb\x72\x3d\x82\x97\x2d\x47\x96\xe5\x06\x2a\xce\x82\x7e\xa6\xda\x95\xaf\xfd\xd7\xaf\x89\xfc\x47\xbe\xfc\x48\x94\x48\x8e\xdf\x4e\x48\xf1\x0f\xd1\x91\xe5\xc6\x62\xa7\x1c\x01\xa2\xc7\x07\xee\x7c\x5c\x3b\x27\xcb\x31\x19\xc6\xbe\x42\x72\x35\x6d\xda\xff\x1d\xf4\x3b\x43\xaf\x3b\xe3\x57\xbb\x33\x43\x1e\xf5\xd6\x86\x14\x78\xb0\x22\x6b\x79\x0c\x14\xf2\x98\x4c\xb7\xa4\x98\x2b\x5b\x9b\x6c\xe7\x41\xa7\xa2\x0f\xea\xc3\x6e\xf0\x1d\xfa\x3d\x6d\x3c\xb6\x6b\xfb\xb0\xb9\x23\xf3\x64\xa9\x5f\xe8\xd5\xb2\x65\x4e\x26\xbc\x39\x21\x85\x03\xb5\xb2\x49\xb5\xa0\xd7\x64\x29\x0e\xfd\x8a\x7e\x2d\x8b\xf7\x42\x45\xbf\xb8\x4b\x8f\x4e\x96\xeb\x0f\xf4\xd0\x3d\x5f\x0b\x17\xe3\x1a\x9f\xb5\xc2\x1b\x7a\xb7\xf4\xdb\xfc\x3a\xaf\x59\xc1\x62\x4c\xde\xd8\x0f\xe9\x7b\x97\xde\x7d\xfd\xdf\xc9\x5b\xdd\xbf\x97\x17\xf9\xe3\x3e\xbd\x5f\xd1\xff\xe6\xfe\x7d\x7c\x54\xfa\xdf\xa5\x97\xeb\x53\x8d\xe4\x50\x3f\xd2\xef\xbe\xfe\xc8\xbe\xbf\x5d\x7f\xee\x30\x9f\x8c\x6b\x5e\xb8\xd7\xc9\x28\xe6\xda\x24\xdf\x37\xa7\xf9\xbf\xa7\x7f\x7a\xf0\x67\x95\x3e\xa4\x7a\x5a\xe9\x24\x35\xf0\x63\x52\x52\x7a\x9a\x4d\xf6\xe1\xfc\xa8\x97\x35\x49\xa1\xc6\xac\xc7\xbf\xaa\xbf\x94\xb5\x12\x32\xe8\x35\x6b\xa4\xd0\x4e\x17\x39\x39\x2d\x83\x84\xa4\x8c\xf8\x40\x4a\x9d\xbe\xf6\xe1\xbe\x76\x4a\x5a\x6a\x25\xdf\x77\xf4\x47\xfa\xdd\x9d\xff\xab\xf4\x91\x7d\xee\xc6\x6b\xbf\x6f\x4d\xf3\x1a\x93\xfa\xfa\xef\xa1\x07\xd2\xd6\xba\x92\xe7\x3d\xbd\x9b\x2f\xd8\xbf\x40\xf4\xc9\xe1\x29\xb0\xef\xd3\x13\x99\xf6\x96\x7c\xf5\xdf\xec\x73\x72\x77\xe9\x03\x1e\xd1\x47\xfe\x2a\xc5\x65\x40\xa2\x7b\x48\x4f\x1b\xff\x0e\x52\x9f\xd2\x47\xf4\x32\xe3\x37\x8d\x27\x43\x51\x96\xc7\x8e\x2d\xcb\x4a\xa1\x14\xb2\x5c\xc8\x03\x08\xca\x75\x59\x6e\x20\x28\x76\xe4\xe6\x77\xef\xd1\xf8\xb1\x3c\x96\x65\x85\xed\x14\x17\x7a\xf2\xb7\x6f\xd5\xae\x10\x6d\x45\x7e\xb9\xd9\x80\x7c\x25\xab\xa6\x1f\xbe\x92\xf0\x71\xe2\x97\x1f\xbe\xc2\xe7\x8d\x5f\x7e\xc0\xb0\xaf\xf0\x11\xda\x33\xbf\x3d\xdc\x3c\xb5\x3c\xc0\x8e\xfb\x5d\xe8\xf1\xff\x01\x33\x7c\x2d\x4d\xbf\x3d\xa0\xc7\x17\xd4\xf2\xcb\xff\x0e\xf5\x34\xfe\xf2\x95\x34\xbd\xfc\x3b\xb3\xe1\x73\xd4\x85\xfa\x65\xc4\x85\xd2\xdb\x07\xac\x87\x5f\xbe\x6a\x97\x95\xee\xba\x3c\x5f\x96\xe5\x07\x2c\x83\x9b\x94\xec\xdb\xc3\xbf\x74\x5f\x0b\xf7\x0f\xd5\x22\x19\x46\x51\x6c\x85\x56\x82\x85\x51\x62\xd9\x56\x92\x40\x25\x64\x3d\x3a\x66\x68\x1b\xf4\x95\xd4\x7e\xb9\x11\xed\xdf\x63\xfd\xa3\x17\xa6\x99\xe6\xfb\xbf\x47\x84\x6e\x35\xe5\xf7\x08\x51\x3d\x82\xfe\x89\x16\xf8\x93\xf8\xfe\x01\xf5\xef\x4a\x70\xbd\xc6\xb0\x0f\x1c\x1d\x2f\x73\x8f\x3a\x61\x44\x41\xb5\x0b\x33\xbd\x04\xf7\x42\xd3\x3a\xe1\x6e\x16\xf8\xa4\x97\xa6\x47\x2b\x25\x7f\x8f\x20\x2f\xbc\x30\xec\x6b\x9a\x3b\x97\xd7\xc2\x1f\x3e\x7f\x2d\xfc\xe1\xe5\xb5\xf0\x07\x0a\xa3\x30\x20\x12\x2c\x46\x83\x87\x5f\xbe\x1a\x5e\x62\xf8\x16\x66\x9c\xbe\x3d\x08\x04\xf7\x80\x19\xe5\xb7\x07\x96\x10\x1f\xb0\xe4\xdb\x03\x78\x20\xdf\x0c\x00\x80\x00\x77\x46\x5c\x7e\xc5\xf6\x61\x80\xde\x6f\x15\x09\xd6\xc0\x29\xf4\x9e\x09\x87\x7e\x2d\x9e\x46\xef\xd0\x70\xe8\x9d\x37\xf4\x02\x19\x85\x33\x18\xb8\xbc\x2e\xc5\x75\xe0\xa4\xf3\x1b\x32\x22\xc1\x61\x12\x21\x74\x38\x44\x07\xa3\x08\x11\xa7\xd0\xaf\xf9\x0b\xe8\x13\x32\xa1\x30\x1a\xbd\xae\x20\x62\x2c\xfa\x47\x63\x1c\x41\x2f\xa5\xf7\x94\x00\x43\xb0\x88\x94\x44\x48\xb9\x40\x48\x06\x4d\xb0\x38\x45\xb0\x70\x06\x92\x87\x45\xaf\x56\xd1\x0d\xc0\x12\x00\x03\x97\x97\x81\x24\x0c\x40\xbe\xd7\xc9\xe7\xf7\x56\xe0\x08\xa1\xb2\x02\xa0\x09\xe9\xbe\xa1\xb8\xab\xa1\x00\x47\xb0\x9f\x0d\x61\x2e\x43\xa8\x4f\x86\xd0\xbf\xca\x87\x79\xa1\xf1\x19\x1b\xe6\x45\x90\x37\x5c\x60\x48\xdc\x04\x2c\xa9\xbd\x44\xf2\x0d\xe0\x5d\x2f\x5f\x2f\xae\x10\x78\xd9\xff\xbf\xc7\xd5\xb7\x27\x3c\x2f\xa8\x7a\x39\xbd\x78\x39\xae\x78\xf8\x24\x6d\xaa\x63\xff\xdb\xd8\xee\xc2\x24\xc1\x22\xfb\xa6\xe9\xe9\x09\x4b\xb4\xd0\xb1\x30\xa2\x9e\x58\x9a\x69\x24\xc7\x40\x4f\x31\xfc\xf9\xf9\x66\x0c\xf9\xf4\x84\x79\xf6\xeb\x62\x71\xcd\xc7\xa7\x27\xec\x7f\x25\x51\x94\x11\xed\xea\xd9\x68\x31\x55\xb1\xe7\xe7\x97\x65\xe5\xbf\xb0\x63\xe2\x37\x53\x43\x8b\x2d\xf4\x8c\x0b\x3b\x86\x5a\x60\xa1\xf5\x46\x83\xb7\x96\x9f\x5a\x97\x19\x97\x0e\xd8\x18\x9a\xd8\x1b\xf6\x4f\x4f\xf8\x75\xe4\x5b\xc1\xaf\x02\xbd\x6d\x7d\x37\xff\x2b\xf9\xde\x0e\x17\x6d\x3a\x5a\xfa\x66\xf2\x2d\xec\xbd\x9c\xbb\xbd\x81\x06\xc8\xf2\xc3\x2c\xf2\x8d\xd1\xdf\xf3\x7f\xd3\x7d\x61\x3c\xf3\xce\x37\xba\xdc\xb2\x7d\x73\xc8\xf9\xf6\xcc\xe9\x72\xc6\xf4\xf0\xd1\xbf\xd5\xca\x0a\x65\xbb\x10\x7e\xaf\xf1\x7b\x19\x6e\x04\x7c\xbf\x1e\x5f\xe4\x78\x7f\x6a\x75\x0d\x4c\xd4\xfe\x42\x36\x4b\x6e\x84\xc9\xcc\x97\xc9\xd7\x43\xdc\xb7\xb0\xfa\xde\xba\x17\x50\xfe\xb8\x31\xa8\xe4\xca\xcc\x37\xc4\xdf\x90\x7a\x8d\x3f\xa2\xae\x19\x7b\x15\x3e\x0b\xdf\x04\x1b\x8c\x35\x82\xb8\x49\xc2\x7b\xf4\xbe\xdf\xf2\x95\x7c\x55\xee\x35\x43\x54\x2f\xcd\xbc\xd0\xb9\xf1\xdd\xbf\x6d\x82\xa7\x27\xd8\xdd\x4a\xa2\xa0\x79\xca\xaa\xe8\x87\x62\xff\x21\x63\xfc\xb6\xb4\xfb\x9c\xec\xbd\x28\x7c\x1f\xff\xf7\x12\x07\x09\xf1\x21\x71\x2a\xb1\xaa\x29\x15\x4a\x28\xc3\x19\x72\xd5\xf3\xf3\xcb\x4a\x6e\x78\xe6\xcb\x81\xca\x8f\x2f\xe9\xf5\xd6\x97\x9f\x2d\xe3\xd7\xd5\x1b\xbb\xae\xe8\x0f\xaf\x88\xf2\x09\x34\x55\xdb\x85\xfb\x7c\xfe\xaf\xed\xf9\x16\x3a\x98\x79\x31\xd8\x3b\x4b\xbe\xa4\xce\xad\x4d\x2a\x54\x98\xb9\x51\x92\xdd\xb1\xcb\xad\xbd\xef\x83\xd3\x6f\xf2\xc1\x9b\xe4\xfe\x34\x4a\xdf\xe4\xf5\x4d\xaa\xbe\x5f\x78\xbe\x92\xd5\xe6\xfe\x2b\x09\xb7\x4b\xbf\xfc\xf0\xdf\x01\x00\x00\xff\xff\x3d\x80\xde\xff\x59\x6f\x01\x00") func dirIndexHtmlDirIndexHtmlBytes() ([]byte, error) { return bindataRead( @@ -241,7 +241,7 @@ func dirIndexHtmlDirIndexHtml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "dir-index-html/dir-index.html", size: 93884, mode: os.FileMode(420), modTime: time.Unix(1403768328, 0)} + info := bindataFileInfo{name: "dir-index-html/dir-index.html", size: 94041, mode: os.FileMode(420), modTime: time.Unix(1403768328, 0)} a := &asset{bytes: bytes, info: info} return a, nil } diff --git a/assets/bindata_version_hash.go b/assets/bindata_version_hash.go index c281dd0f00d..07286e7fad6 100644 --- a/assets/bindata_version_hash.go +++ b/assets/bindata_version_hash.go @@ -2,5 +2,5 @@ package assets const ( - BindataVersionHash = "514e5ae28d8adb84955801b56ef47aca44bf9cc8" + BindataVersionHash = "605b5945438e1fe2eaf8a6571cca7ecda12d5599" ) diff --git a/assets/dir-index-html b/assets/dir-index-html index 9603194e10c..92efd3dfd1c 160000 --- a/assets/dir-index-html +++ b/assets/dir-index-html @@ -1 +1 @@ -Subproject commit 9603194e10c40ca8585497828fc4a7b7c72dea90 +Subproject commit 92efd3dfd1cdaf2ca50b34b2b5d1243c5dcc8af7 diff --git a/core/corehttp/gateway_handler.go b/core/corehttp/gateway_handler.go index cff82fef7f5..e531640da3c 100644 --- a/core/corehttp/gateway_handler.go +++ b/core/corehttp/gateway_handler.go @@ -391,13 +391,16 @@ func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request 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, gwURL), + Breadcrumbs: breadcrumbs(urlPath, dnslink), BackLink: backLink, Hash: hash, } diff --git a/core/corehttp/gateway_indexPage.go b/core/corehttp/gateway_indexPage.go index 5cbf33becfd..f735aa0e6b4 100644 --- a/core/corehttp/gateway_indexPage.go +++ b/core/corehttp/gateway_indexPage.go @@ -13,6 +13,7 @@ import ( // structs for directory listing type listingTemplateData struct { GatewayURL string + DNSLink bool Listing []directoryItem Size string Path string @@ -34,7 +35,7 @@ type breadcrumb struct { Path string } -func breadcrumbs(urlPath string, gwRootURL string) []breadcrumb { +func breadcrumbs(urlPath string, dnslinkOrigin bool) []breadcrumb { var ret []breadcrumb p, err := ipfspath.ParsePath(urlPath) @@ -43,7 +44,6 @@ func breadcrumbs(urlPath string, gwRootURL string) []breadcrumb { return ret } segs := p.Segments() - ns := segs[0] contentRoot := segs[1] for i, seg := range segs { if i == 0 { @@ -56,10 +56,11 @@ func breadcrumbs(urlPath string, gwRootURL string) []breadcrumb { } } - // Drop the /ipns/ prefix from breadcrumb Paths when directory listing - // on a DNSLink website (loaded due to Host header in HTTP request). - // Necessary because gwRootURL won't have a public gateway mounted. - if ns == "ipns" && (("//" + contentRoot) == gwRootURL) { + // Drop the /ipns/ prefix from breadcrumb Paths when directory + // listing on a DNSLink website (loaded due to Host header in HTTP + // request). Necessary because the hostname most likely won't have a + // public gateway mounted. + if dnslinkOrigin { prefix := "/ipns/" + contentRoot for i, crumb := range ret { if strings.HasPrefix(crumb.Path, prefix) { @@ -77,6 +78,16 @@ func shortHash(hash string) string { return (hash[0:4] + "\u2026" + hash[len(hash)-4:]) } +// helper to detect DNSLink website context +// (when hostname from gwURL is matching /ipns/ in path) +func hasDNSLinkOrigin(gwURL string, path string) bool { + if gwURL != "" { + dnslinkRoot := strings.Replace(gwURL, "//", "/ipns/", 1) + return strings.HasPrefix(path, dnslinkRoot) + } + return false +} + var listingTemplate *template.Template func init() { From 3ed46d995fee555f924b9163e491e37845ad8818 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Tue, 29 Sep 2020 02:27:28 +0200 Subject: [PATCH 021/116] test(gw): add t0115-gateway-dir-listing.sh to sharness This adds proper end-to-end tests for directory listing on Gateway port that protects us against regressions oni each gw type: - path gateway - subdomain gateway - dnslink website gateway Tests cover: - etag/unicode support - breadcrumbs - file name column - hash column --- core/corehttp/gateway_handler.go | 4 - core/corehttp/gateway_indexPage.go | 4 +- core/corehttp/gateway_test.go | 12 +- test/sharness/t0114-gateway-subdomains.sh | 3 +- test/sharness/t0115-gateway-dir-listing.sh | 146 +++++++++++++++++++++ 5 files changed, 161 insertions(+), 8 deletions(-) create mode 100755 test/sharness/t0115-gateway-dir-listing.sh diff --git a/core/corehttp/gateway_handler.go b/core/corehttp/gateway_handler.go index e531640da3c..9af249520b3 100644 --- a/core/corehttp/gateway_handler.go +++ b/core/corehttp/gateway_handler.go @@ -405,10 +405,6 @@ func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request Hash: hash, } - // TODO: remove logging below - // tplDataJSON, _ := json.MarshalIndent(tplData, "", " ") - // fmt.Println(string(tplDataJSON)) - err = listingTemplate.Execute(w, tplData) if err != nil { internalWebError(w, err) diff --git a/core/corehttp/gateway_indexPage.go b/core/corehttp/gateway_indexPage.go index f735aa0e6b4..6e172211638 100644 --- a/core/corehttp/gateway_indexPage.go +++ b/core/corehttp/gateway_indexPage.go @@ -82,8 +82,8 @@ func shortHash(hash string) string { // (when hostname from gwURL is matching /ipns/ in path) func hasDNSLinkOrigin(gwURL string, path string) bool { if gwURL != "" { - dnslinkRoot := strings.Replace(gwURL, "//", "/ipns/", 1) - return strings.HasPrefix(path, dnslinkRoot) + fqdn := stripPort(strings.TrimPrefix(gwURL, "//")) + return strings.HasPrefix(path, "/ipns/"+fqdn) } return false } diff --git a/core/corehttp/gateway_test.go b/core/corehttp/gateway_test.go index 46bf76a5e69..f98b4a7737b 100644 --- a/core/corehttp/gateway_test.go +++ b/core/corehttp/gateway_test.go @@ -393,6 +393,8 @@ func TestIPNSHostnameRedirect(t *testing.T) { // Test directory listing on DNSLink website // (scenario when Host header is the same as URL hostname) +// This is basic regression test: additional end-to-end tests +// can be found in test/sharness/t0115-gateway-dir-listing.sh func TestIPNSHostnameBacklinks(t *testing.T) { ns := mockNamesys{} ts, api, ctx := newTestServerAndNode(t, ns) @@ -439,7 +441,7 @@ func TestIPNSHostnameBacklinks(t *testing.T) { t.Fatal(err) } - // expect correct backlinks + // expect correct links body, err := ioutil.ReadAll(res.Body) if err != nil { t.Fatalf("error reading response: %s", err) @@ -456,6 +458,10 @@ func TestIPNSHostnameBacklinks(t *testing.T) { if !strings.Contains(s, "") { t.Fatalf("expected file in directory listing") } + if !strings.Contains(s, "") { t.Fatalf("expected file in directory listing") } + if !strings.Contains(s, "bar" list_response ' -# Note we test for sneaky subdir names {cid}.ipfs.example.com/ipfs/ipns/ :^) +# Note 1: we test for sneaky subdir names {cid}.ipfs.example.com/ipfs/ipns/ :^) +# Note 2: example.com/ipfs/.. present in HTML will be redirected to subdomain, so this is expected behavior test_expect_success "valid breadcrumb links in the header of directory listing at {cid}.ipfs.example.com/sub/dir" ' curl -s -H "Host: $DIR_FQDN" http://127.0.0.1:$GWAY_PORT/ipfs/ipns/ > list_response && test_should_contain "Index of" list_response && diff --git a/test/sharness/t0115-gateway-dir-listing.sh b/test/sharness/t0115-gateway-dir-listing.sh new file mode 100755 index 00000000000..17740a3b89f --- /dev/null +++ b/test/sharness/t0115-gateway-dir-listing.sh @@ -0,0 +1,146 @@ +#!/usr/bin/env bash +# +# Copyright (c) Protocol Labs + +test_description="Test directory listing (dir-index-html) on the HTTP gateway" + + +. lib/test-lib.sh + +## ============================================================================ +## Start IPFS Node and prepare test CIDs +## ============================================================================ + +test_expect_success "ipfs init" ' + export IPFS_PATH="$(pwd)/.ipfs" && + ipfs init --profile=test > /dev/null +' + +test_launch_ipfs_daemon --offline + +test_expect_success "Add the test directory" ' + mkdir -p rootDir/ipfs && + mkdir -p rootDir/ipns && + mkdir -p rootDir/api && + mkdir -p rootDir/ą/ę && + echo "I am a txt file on path with utf8" > rootDir/ą/ę/file-źł.txt && + echo "I am a txt file in confusing /api dir" > rootDir/api/file.txt && + 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) +' + +## ============================================================================ +## Test dir listing on path gateway (eg. 127.0.0.1:8080/ipfs/) +## ============================================================================ + +test_expect_success "path gw: backlink on root CID should point at self" ' + curl -sD - http://127.0.0.1:$GWAY_PORT/ipfs/${DIR_CID}/ > list_response && + test_should_contain "Index of" list_response && + test_should_contain ".." list_response +' + +test_expect_success "path gw: Etag should be present" ' + curl -sD - http://127.0.0.1:$GWAY_PORT/ipfs/${DIR_CID}/ą/ę > list_response && + test_should_contain "Index of" list_response && + test_should_contain "Etag: \"DirIndex-" list_response +' + +test_expect_success "path gw: breadcrumbs should point at /ipfs namespace mounted at Origin root" ' + test_should_contain "/ipfs/$DIR_CID/ą/ę" list_response +' + +test_expect_success "path gw: backlink should point at parent directory" ' + test_should_contain ".." list_response +' + +test_expect_success "path gw: name column should be a link to its content path" ' + test_should_contain "file-źł.txt" list_response +' + +test_expect_success "path gw: hash column should be a CID link with filename param" ' + test_should_contain "" list_response +' + +## ============================================================================ +## Test dir listing on subdomain gateway (eg. .ipfs.localhost:8080) +## ============================================================================ + +DIR_HOSTNAME="${DIR_CID}.ipfs.localhost" +# note: we skip DNS lookup by running curl with --resolve $DIR_HOSTNAME:127.0.0.1 + +test_expect_success "path gw: backlink on root CID should point origin root" ' + curl -sD - --resolve $DIR_HOSTNAME:127.0.0.1 http://$DIR_HOSTNAME:$GWAY_PORT/ > list_response && + test_should_contain "Index of" list_response && + test_should_contain ".." list_response +' + +test_expect_success "path gw: Etag should be present" ' + curl -sD - --resolve $DIR_HOSTNAME:127.0.0.1 http://$DIR_HOSTNAME:$GWAY_PORT/ą/ę > list_response && + test_should_contain "Index of" list_response && + test_should_contain "Etag: \"DirIndex-" list_response +' + +test_expect_success "subdomain gw: breadcrumbs should leverage path-based router mounted on the parent domain" ' + test_should_contain "/ipfs/$DIR_CID/ą/ę" list_response +' + +test_expect_success "path gw: name column should be a link to content root mounted at subdomain origin" ' + test_should_contain "file-źł.txt" list_response +' + +test_expect_success "path gw: hash column should be a CID link to path router with filename param" ' + test_should_contain "" list_response +' + +## ============================================================================ +## Test dir listing on DNSLink gateway (eg. example.com) +## ============================================================================ + +# DNSLink test requires a daemon in online mode with precached /ipns/ mapping +test_kill_ipfs_daemon +DNSLINK_HOSTNAME="website.example.com" +export IPFS_NS_MAP="$DNSLINK_HOSTNAME:/ipfs/$DIR_CID" +test_launch_ipfs_daemon + +# Note that: +# - this type of gateway is also tested in gateway_test.go#TestIPNSHostnameBacklinks +# (go tests and sharness tests should be kept in sync) +# - we skip DNS lookup by running curl with --resolve $DNSLINK_HOSTNAME:127.0.0.1 + +test_expect_success "dnslink gw: backlink on root CID should point origin root" ' + curl -v -sD - --resolve $DNSLINK_HOSTNAME:$GWAY_PORT:127.0.0.1 http://$DNSLINK_HOSTNAME:$GWAY_PORT/ > list_response && + test_should_contain "Index of" list_response && + test_should_contain ".." list_response +' + +test_expect_success "dnslink gw: Etag should be present" ' + curl -sD - --resolve $DNSLINK_HOSTNAME:$GWAY_PORT:127.0.0.1 http://$DNSLINK_HOSTNAME:$GWAY_PORT/ą/ę > list_response && + test_should_contain "Index of" list_response && + test_should_contain "Etag: \"DirIndex-" list_response +' + +test_expect_success "dnslink gw: breadcrumbs should point at content root mounted at dnslink origin" ' + test_should_contain "/ipns/website.example.com/ą/ę" list_response +' + +test_expect_success "dnslink gw: name column should be a link to content root mounted at dnslink origin" ' + test_should_contain "file-źł.txt" list_response +' + +# DNSLink websites don't have public gateway mounted by default +# See: https://github.com/ipfs/dir-index-html/issues/42 +test_expect_success "dnslink gw: hash column should be a CID link to cid.ipfs.io" ' + test_should_contain "" list_response +' + +## ============================================================================ +## End of tests, cleanup +## ============================================================================ + +test_kill_ipfs_daemon +test_expect_success "clean up ipfs dir" ' + rm -rf "$IPFS_PATH" +' +test_done From 4deaf050d7730908b73c45b7e726eb129bdf243f Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Tue, 29 Sep 2020 02:30:48 +0200 Subject: [PATCH 022/116] chore: dir-index-html 1.2.1 release notes: https://github.com/ipfs/dir-index-html/releases/tag/1.2.1 --- assets/dir-index-html | 2 +- test/sharness/t0115-gateway-dir-listing.sh | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/assets/dir-index-html b/assets/dir-index-html index 92efd3dfd1c..5c6147fd02e 160000 --- a/assets/dir-index-html +++ b/assets/dir-index-html @@ -1 +1 @@ -Subproject commit 92efd3dfd1cdaf2ca50b34b2b5d1243c5dcc8af7 +Subproject commit 5c6147fd02e88b0a235ac655f58741436a2f2b80 diff --git a/test/sharness/t0115-gateway-dir-listing.sh b/test/sharness/t0115-gateway-dir-listing.sh index 17740a3b89f..d7808a261a9 100755 --- a/test/sharness/t0115-gateway-dir-listing.sh +++ b/test/sharness/t0115-gateway-dir-listing.sh @@ -71,13 +71,13 @@ DIR_HOSTNAME="${DIR_CID}.ipfs.localhost" # note: we skip DNS lookup by running curl with --resolve $DIR_HOSTNAME:127.0.0.1 test_expect_success "path gw: backlink on root CID should point origin root" ' - curl -sD - --resolve $DIR_HOSTNAME:127.0.0.1 http://$DIR_HOSTNAME:$GWAY_PORT/ > list_response && + curl -sD - --resolve $DIR_HOSTNAME:$GWAY_PORT:127.0.0.1 http://$DIR_HOSTNAME:$GWAY_PORT/ > list_response && test_should_contain "Index of" list_response && test_should_contain ".." list_response ' test_expect_success "path gw: Etag should be present" ' - curl -sD - --resolve $DIR_HOSTNAME:127.0.0.1 http://$DIR_HOSTNAME:$GWAY_PORT/ą/ę > list_response && + curl -sD - --resolve $DIR_HOSTNAME:$GWAY_PORT:127.0.0.1 http://$DIR_HOSTNAME:$GWAY_PORT/ą/ę > list_response && test_should_contain "Index of" list_response && test_should_contain "Etag: \"DirIndex-" list_response ' From df33dc43dbe554be8312d3ece5bf3f72dad36e9c Mon Sep 17 00:00:00 2001 From: Andrew Nesbitt Date: Fri, 2 Oct 2020 14:58:34 +0100 Subject: [PATCH 023/116] Add task for updating CLI docs right after updating the HTTP-api docs --- docs/RELEASE_ISSUE_TEMPLATE.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/RELEASE_ISSUE_TEMPLATE.md b/docs/RELEASE_ISSUE_TEMPLATE.md index 2e8774eaf4f..b6ad1fc1b6d 100644 --- a/docs/RELEASE_ISSUE_TEMPLATE.md +++ b/docs/RELEASE_ISSUE_TEMPLATE.md @@ -74,6 +74,7 @@ Checklist: - [ ] Ensure that [README.md](https://github.com/ipfs/go-ipfs/tree/master/README.md) is up to date - [ ] Ensure that all the examples we have produced for go-ipfs run without problems - [ ] Update HTTP-API Documentation on the Website using https://github.com/ipfs/http-api-docs + - [ ] Update [CLI Documentation](https://github.com/ipfs/ipfs-docs/blob/master/docs/reference/cli.md) on the Website using https://github.com/ipfs-inactive/docs/blob/master/scripts/cli.sh - [ ] Invite the IPFS [_early testers_](https://github.com/ipfs/go-ipfs/tree/master/docs/EARLY_TESTERS.md) to deploy the release to part of their production infrastructure. - [ ] Invite the wider community through (link to the release issue): - [ ] [discuss.ipfs.io](https://discuss.ipfs.io/c/announcements) From 00147106f42158fccee0f74373cd86dec977b23d Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Tue, 6 Oct 2020 19:57:18 +0200 Subject: [PATCH 024/116] feat: ipfs-webui v2.11.3 https://github.com/ipfs-shipyard/ipfs-webui/releases/tag/v2.11.3 --- core/corehttp/webui.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/corehttp/webui.go b/core/corehttp/webui.go index c41be6300df..24def6c4d65 100644 --- a/core/corehttp/webui.go +++ b/core/corehttp/webui.go @@ -1,7 +1,7 @@ package corehttp // TODO: move to IPNS -const WebUIPath = "/ipfs/bafybeifekmcbbi4nwyj4aasti6x3nuhyli464wfjjfdjg4xnz53lhyiedq" // v2.11.2 +const WebUIPath = "/ipfs/bafybeigv2xkwu2v27rx56m7ndg5dnz4b7235pn33andlriqhyy5s6nwyvq" // v2.11.3 // this is a list of all past webUI paths. var WebUIPaths = []string{ From f62656630bf6eedd75b6f87f53cae930cd6bb824 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Wed, 7 Oct 2020 15:01:32 +0200 Subject: [PATCH 025/116] feat: ipfs-webui v2.11.4 --- core/corehttp/webui.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/corehttp/webui.go b/core/corehttp/webui.go index 24def6c4d65..b52644c96b0 100644 --- a/core/corehttp/webui.go +++ b/core/corehttp/webui.go @@ -1,7 +1,7 @@ package corehttp // TODO: move to IPNS -const WebUIPath = "/ipfs/bafybeigv2xkwu2v27rx56m7ndg5dnz4b7235pn33andlriqhyy5s6nwyvq" // v2.11.3 +const WebUIPath = "/ipfs/bafybeif4zkmu7qdhkpf3pnhwxipylqleof7rl6ojbe7mq3fzogz6m4xk3i" // v2.11.4 // this is a list of all past webUI paths. var WebUIPaths = []string{ From 9675c2fdd181f8c4390db244ab96b83002b86d8f Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Thu, 8 Oct 2020 17:39:28 +0700 Subject: [PATCH 026/116] update QUIC --- go.mod | 6 ++---- go.sum | 12 ++++-------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index 52161cb35c9..21081465235 100644 --- a/go.mod +++ b/go.mod @@ -2,14 +2,12 @@ module github.com/ipfs/go-ipfs require ( bazil.org/fuse v0.0.0-20200117225306-7b5117fecadc - github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect github.com/blang/semver v3.5.1+incompatible github.com/bren2010/proquint v0.0.0-20160323162903-38337c27106d github.com/cheggaaa/pb v1.0.29 github.com/coreos/go-systemd/v22 v22.1.0 github.com/dustin/go-humanize v1.0.0 github.com/elgris/jsondiff v0.0.0-20160530203242-765b5c24c302 - github.com/fatih/color v1.9.0 // indirect github.com/fsnotify/fsnotify v1.4.9 github.com/gabriel-vasile/mimetype v1.1.1 github.com/go-bindata/go-bindata/v3 v3.1.3 @@ -75,7 +73,7 @@ require ( github.com/libp2p/go-libp2p-peerstore v0.2.6 github.com/libp2p/go-libp2p-pubsub v0.3.5 github.com/libp2p/go-libp2p-pubsub-router v0.3.2 - github.com/libp2p/go-libp2p-quic-transport v0.8.0 + github.com/libp2p/go-libp2p-quic-transport v0.8.2 github.com/libp2p/go-libp2p-record v0.1.3 github.com/libp2p/go-libp2p-routing-helpers v0.2.3 github.com/libp2p/go-libp2p-secio v0.2.2 @@ -86,7 +84,7 @@ require ( github.com/libp2p/go-socket-activation v0.0.2 github.com/libp2p/go-tcp-transport v0.2.1 github.com/libp2p/go-ws-transport v0.3.1 - github.com/lucas-clemente/quic-go v0.18.0 + github.com/lucas-clemente/quic-go v0.18.1 github.com/mattn/go-runewidth v0.0.9 // indirect github.com/mitchellh/go-homedir v1.1.0 github.com/multiformats/go-multiaddr v0.3.1 diff --git a/go.sum b/go.sum index 3343569c9a0..4ed782816aa 100644 --- a/go.sum +++ b/go.sum @@ -326,8 +326,6 @@ github.com/ipfs/go-ds-badger v0.2.1 h1:RsC9DDlwFhFdfT+s2PeC8joxbSp2YMufK8w/RBOxK github.com/ipfs/go-ds-badger v0.2.1/go.mod h1:Tx7l3aTph3FMFrRS838dcSJh+jjA7cX9DrGVwx/NOwE= github.com/ipfs/go-ds-badger v0.2.3 h1:J27YvAcpuA5IvZUbeBxOcQgqnYHUPxoygc6QxxkodZ4= github.com/ipfs/go-ds-badger v0.2.3/go.mod h1:pEYw0rgg3FIrywKKnL+Snr+w/LjJZVMTBRn4FS6UHUk= -github.com/ipfs/go-ds-badger v0.2.4 h1:UPGB0y7luFHk+mY/tUZrif/272M8o+hFsW+avLUeWrM= -github.com/ipfs/go-ds-badger v0.2.4/go.mod h1:pEYw0rgg3FIrywKKnL+Snr+w/LjJZVMTBRn4FS6UHUk= github.com/ipfs/go-ds-badger v0.2.5 h1:oKRP6xVdgunjioOvaW4Ue2N7rBI7h/sWNERHTguUmpE= github.com/ipfs/go-ds-badger v0.2.5/go.mod h1:02rnztVKA4aZwDuaRPTf8mpqcKmXP7mLl6JPxd14JHA= github.com/ipfs/go-ds-flatfs v0.4.5 h1:4QceuKEbH+HVZ2ZommstJMi3o3II+dWS3IhLaD7IGHs= @@ -730,8 +728,8 @@ github.com/libp2p/go-libp2p-pubsub v0.3.5 h1:iF75GWpcxKEUQU8tTkgLy69qIQvfhL+t6U6 github.com/libp2p/go-libp2p-pubsub v0.3.5/go.mod h1:DTMSVmZZfXodB/pvdTGrY2eHPZ9W2ev7hzTH83OKHrI= github.com/libp2p/go-libp2p-pubsub-router v0.3.2 h1:BGC4irCUXlwmlCSxnA2DVDNY8JqhfAUUaiq3CZvcddw= github.com/libp2p/go-libp2p-pubsub-router v0.3.2/go.mod h1:G4MAvYzPxhoR0LEBluS9Ow+Nnr/8iDalUN+RNwVgNkY= -github.com/libp2p/go-libp2p-quic-transport v0.8.0 h1:mHA94K2+TD0e9XtjWx/P5jGGZn0GdQ4OFYwNllagv4E= -github.com/libp2p/go-libp2p-quic-transport v0.8.0/go.mod h1:F2FG/6Bzz0U6essUVxDzE0s9CrY4XGLbl7QEmDNvU7A= +github.com/libp2p/go-libp2p-quic-transport v0.8.2 h1:FDaXBCBJ1e5hY6gnWEJ4NbYyLk8eezr4J6AY3q3KqwM= +github.com/libp2p/go-libp2p-quic-transport v0.8.2/go.mod h1:L+e0q15ZNaYm3seHgbsXjWP8kXLEqz+elLWKk9l8DhM= 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= @@ -893,8 +891,8 @@ github.com/libp2p/go-yamux v1.3.5 h1:ibuz4naPAully0pN6J/kmUARiqLpnDQIzI/8GCOrljg 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/lucas-clemente/quic-go v0.18.0 h1:JhQDdqxdwdmGdKsKgXi1+coHRoGhvU6z0rNzOJqZ/4o= -github.com/lucas-clemente/quic-go v0.18.0/go.mod h1:yXttHsSNxQi8AWijC/vLP+OJczXqzHSOcJrM5ITUlCg= +github.com/lucas-clemente/quic-go v0.18.1 h1:DMR7guC0NtVS8zNZR3IO7NARZvZygkSC56GGtC6cyys= +github.com/lucas-clemente/quic-go v0.18.1/go.mod h1:yXttHsSNxQi8AWijC/vLP+OJczXqzHSOcJrM5ITUlCg= github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 h1:2gxZ0XQIU/5z3Z3bUBu+FXuk2pFbkN6tcwi/pjyaDic= @@ -1531,8 +1529,6 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/cheggaaa/pb.v1 v1.0.28 h1:n1tBJnnK2r7g9OW2btFH91V92STTUevLXYFb8gy9EMk= -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= From 6b83bcd60e9725b412beb11dde03918929e9429b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Zdyba=C5=82?= Date: Mon, 12 Oct 2020 00:10:42 +0200 Subject: [PATCH 027/116] Add missing plugin support on FreeBSD Go plugins are supported on FreeBSD, but build tags in `plugin/loader/load_*.go` enable IPFS plugins only on Linux and Darwin. --- plugin/loader/load_nocgo.go | 2 +- plugin/loader/load_unix.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugin/loader/load_nocgo.go b/plugin/loader/load_nocgo.go index d0947cfc747..3c73059e16c 100644 --- a/plugin/loader/load_nocgo.go +++ b/plugin/loader/load_nocgo.go @@ -1,5 +1,5 @@ // +build !cgo,!noplugin -// +build linux darwin +// +build linux darwin freebsd package loader diff --git a/plugin/loader/load_unix.go b/plugin/loader/load_unix.go index b31b9fe9d46..e7d744cbd97 100644 --- a/plugin/loader/load_unix.go +++ b/plugin/loader/load_unix.go @@ -1,5 +1,5 @@ // +build cgo,!noplugin -// +build linux darwin +// +build linux darwin freebsd package loader From f69b067ed36ecb2a8fae85ce6d7b019d64fa8bb8 Mon Sep 17 00:00:00 2001 From: Oli Evans Date: Mon, 12 Oct 2020 18:13:09 +0100 Subject: [PATCH 028/116] docs: add notes on snap build and publish License: MIT Signed-off-by: Oli Evans --- docs/snap.md | 201 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 docs/snap.md diff --git a/docs/snap.md b/docs/snap.md new file mode 100644 index 00000000000..203f7a5660f --- /dev/null +++ b/docs/snap.md @@ -0,0 +1,201 @@ +# Publishing go-ipfs as a snap + +> Snap is the default package manager for ubuntu since the release of 20.04. This doc captures what we know about building go-ipfs as a snap packge and publishing it to the snapstore. + +The go-ipfs snap is defined in [snap/snapcraft.yaml](https://github.com/ipfs/go-ipfs/blob/master/snap/snapcraft.yaml). For more detail on our snapcraft.yaml see: https://github.com/ipfs-shipyard/ipfs-snap + +- go-ipfs is published as `ipfs` to the snapcraft store, see: https://snapcraft.io/ipfs +- ipfs-desktop is published as `ipfs-desktop`, from CI, here: https://github.com/ipfs-shipyard/ipfs-desktop/blob/master/.github/workflows/snapcraft.yml + +For go-ipfs we deliberately lean on the Canonical lauchpad.net build environment so as it simplifies creating builds for more architectures, which has been requested by user numerous times. + +Linux user can install go-ipfs with: + +``` +$ snap install ipfs +``` + +Apps installed via Snapcraft are auto-updating by default. Snapcraft uses 'Release Channels' to let the user pick their stability level, with channels for `stable`, `candidate`, `beta` and `edge`. Snap will install the lasest release from the `stable` channel by default. A user that wants to test out the bleeding edge can opt in by passing the `--edge` flag + +``` +$ snap install --edge ipfs +``` + +Dashboard for managaing go-ipfs snap release channels for go-ipfs + +## Known issues + +- `ipfs mount` fails as fusermount is not included in the snap, and cannot work from a snap as it is not able to create non-root mounts, see: https://github.com/elopio/ipfs-snap/issues/6 + +```console +ubuntu@primary:~$ ipfs mount +2020-07-10T09:54:17.458+0100 ERROR node node/mount_unix.go:91 error mounting: fusermount: exec: "fusermount": executable file not found in $PATH +2020-07-10T09:54:17.463+0100 ERROR node node/mount_unix.go:95 error mounting: fusermount: exec: "fusermount": executable file not found in $PATH +``` + +## Developing + +We let launchpad.net build our snap for us, but if you need to edit the snapcraft.yml you can test it locally + +### Requirements + + You need `snapcraft` installed locally + +```console +# ubuntu or similar +$ snap install snapcraft --classic + +# macos +$ brew install snapcraft +``` + +### Build and test + +**Build** out a snap package for go-ipfs by running the following from this project + +```console +$ snapcraft +``` + +**Test** the built snap package by installing it on a system that has `snapd` + +``` +$ snap install ipfs_.snap +# then kick the tires +$ ubuntu@primary:~$ ipfs daemon +Initializing daemon... +go-ipfs version: 0.7.0-dev +``` + +You can test it out on mac too. By installing and using `snapcraft`, it'll pull in `multipass` which is a quick way to run an ubuntu vm, and it has a notion of a primary container, which gets nice things like automounting your home dir in the vm, so you can: + +```console +# install your .snap in a multipass vm +$ multipass shell +ubuntu@primary:~$ cd ~/Home/path/to/snap/on/host/filesystem +ubuntu@primary:~$ snap install ipfs_.snap --devmode --dangerous +ubuntu@primary:~$ ipfs daemon +Initializing daemon... +go-ipfs version: 0.7.0-dev +``` + +### Building in Docker + +[ipfs-shipyard/ipfs-snap](https://github.com/ipfs-shipyard/ipfs-snap) includes a Dockerfile that creates an image that can build go-ipfs from source and package it as a snap. It starts with `snapcore/snapcraft:stable` and adds in `go` and just enough tools to allow snapcraft to build go-ipfs. It is published to dockerhub as `ipfs/ipfs-snap-builder`. + +```console +$ docker run -v $(pwd):/my-snap ipfs/ipfs-snap-builder:latest sh -c "apt update && cd /my-snap && snapcraft --debug" +``` + +## Publishing the Snap + +The following snap release channels are published automatically: + +| Git branch | Snap channel | +|------------|--------------| +| `release` | `stable` +| `master` | `edge` + + +### Edge via snapcraft.io + +The snapcraft store watches the default branch of the go-ipfs repo, and updates the snap for the `edge` channel. This service is configured automatically by snapcraft. It's neat, but it doesn't allow us to watch any branch other than the default. + +Screenshot 2020-10-12 at 15 56 07 + + +### Stable via launchpad.net + +The `stable` channel is published automatically via launchpad.net. There is a mirror of the go-ipfs repo at https://launchpad.net/go-ipfs that is sync'd with the github repo every few hours (at canonical's leisure). + +A snap build configuration called `ipfs-stable` is set up to watch the `release` branch on go-ipfs and publish it to the `stable` snap channel. + +The key configuration points are: + +```yaml +# What flavour VM to build on. +Series: infer from snapcraft.yml + +Source: + Git: + # the launchpad mirror of go-ipfs + Git repository: ~ipfs/go-ipfs/+git/go-ipfs + Git branch: refs/heads/release + +Automatically build when branch changes: true + Source snap channels for automatic builds: + # tell snapcraft what version of snapcraft to use when building. + # NOTE: At time of writing we use the default `core18` platform for the + # go-ipfs snap. If you specify others here, a build error occurs, which + # I think is mainly due to a launchpad ux bug here. + core: "" + core18: stable + core20: "" + snapcraft: stable + + +Automatically upload to store: + Registered store package name: ipfs + Store channels: + Risk: + Stable: true + +# What architectures to build for. this selection is chosen to match the auto +# configured build provided by snapcraft for the edge channel, for neatness, so +# that all architectures that currently have builds in snap continue to get +# updates, even though some of them would be tough for use to test on. +Processors: + amd64: true + # raspi 4 + arm64: true + # older raspi + armhf: true + # sure ok i guess. + i386: true + # hmmm... PowerPC!? + ppc64el: true + # wat. IBM system Z mainframes!? + s390x: true +``` + +![Screenshot_2020-10-12 Edit ipfs-stable Snap packages “IPFS Maintainers” team](https://user-images.githubusercontent.com/58871/95762510-b4f4a080-0ca5-11eb-8148-d208f891d202.png) + +### Future work - Publish RCs to the `candidate` channel + +If we wish to publish release candidates to the snap store, we can do that by creating a new snap build config + +1. Find the `release-vX.X` branch in the lauchpad.net mirror of the go-ipfs repo. + - e.g. https://code.launchpad.net/~ipfs/go-ipfs/+git/go-ipfs/+ref/release-v0.7.0 +2. Click "Create snap package" +3. Fill out the form using the same values as listed above for the stable channel, but: + - Set `Name` to `ipfs-candidate` _(this just needs to be a unique name to identify this config)_ + - For `Risk` select only `Candidate` _(so the snap is published to the `Candidate` channel.)_ + +You can trigger a build manually to kick things off. Subsequent changes to that branch will be published as a snap automatically when when the mirror next syncs with github (every 6-12hrs) + + +## Who can edit this? + +The `ipfs` snapcraft.io listing can be edited by + +- @elopio _TBC, the original submitter, need to check about getting ownership transferred._ +- @lidel +- @olizilla + +You need a Canonical developer account, then ask an existing owner to add you. Accsess is managed here https://dashboard.snapcraft.io/snaps/ipfs/collaboration/ + + +The launchpad.net config is managed by [**IPFS Maintainers**](https://launchpad.net/~ipfs) team, and you can request to join that team with your Canonical developer acccount. The list of maintainers is here: https://launchpad.net/~ipfs/+members + +At the time of writing the launchpad maintainers are: + +- @lidel +- @olizilla + + +## References + +- Walkthrough of publishing a snap package via snapcraft and launchpad: https://www.youtube.com/watch?v=X_U-pcvBFrU +- For more details on the go-ipfs snapcraft.yaml see: https://github.com/ipfs-shipyard/ipfs-snap +- publishing to multiple channels via build.snapcraft.io: https://forum.snapcraft.io/t/maintaining-and-publishing-multiple-to-multiple-channels-via-build-snapcraft-io/12455 +- How node.js manages snaps: https://github.com/ipfs/go-ipfs/issues/7679#issuecomment-695914986 From 3df743ac2976d3a2c9aa5109647fd593b5d325be Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 12 Oct 2020 16:35:31 -0700 Subject: [PATCH 029/116] fix error when computing coverage Some packages can contain both external and internal tests. Listing these packages twice causes us to create two targets (which fails). Instead, use a single go list statement. --- coverage/Rules.mk | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/coverage/Rules.mk b/coverage/Rules.mk index b8afab6d4e8..e0935d880ba 100644 --- a/coverage/Rules.mk +++ b/coverage/Rules.mk @@ -13,8 +13,7 @@ endif .PHONY: $(d)/coverage_deps # unit tests coverage -UTESTS_$(d) := $(shell $(GOCC) list -f '{{if (len .TestGoFiles)}}{{.ImportPath}}{{end}}' $(go-flags-with-tags) ./...) -UTESTS_$(d) += $(shell $(GOCC) list -f '{{if (len .XTestGoFiles)}}{{.ImportPath}}{{end}}' $(go-flags-with-tags) ./... | grep -v go-ipfs/vendor | grep -v go-ipfs/Godeps) +UTESTS_$(d) := $(shell $(GOCC) list -f '{{if (or (len .TestGoFiles) (len .XTestGoFiles))}}{{.ImportPath}}{{end}}' $(go-flags-with-tags) ./... | grep -v go-ipfs/vendor | grep -v go-ipfs/Godeps) UCOVER_$(d) := $(addsuffix .coverprofile,$(addprefix $(d)/unitcover/, $(subst /,_,$(UTESTS_$(d))))) From 6ffd0aa22ea6a454740c3b8c83a566d4faa3dc62 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Wed, 14 Oct 2020 00:46:57 +0200 Subject: [PATCH 030/116] fix(gw): preserve query on website redirect --- core/corehttp/gateway_handler.go | 7 ++++++- test/sharness/t0110-gateway.sh | 13 ++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/core/corehttp/gateway_handler.go b/core/corehttp/gateway_handler.go index b7a2b7e38c1..30d2a563e7c 100644 --- a/core/corehttp/gateway_handler.go +++ b/core/corehttp/gateway_handler.go @@ -290,7 +290,12 @@ func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request goget := r.URL.Query().Get("go-get") == "1" if dirwithoutslash && !goget { // See comment above where originalUrlPath is declared. - http.Redirect(w, r, originalUrlPath+"/", 302) + suffix := "/" + if r.URL.RawQuery != "" { + // preserve query parameters + suffix = suffix + "?" + r.URL.RawQuery + } + http.Redirect(w, r, originalUrlPath+suffix, 302) return } diff --git a/test/sharness/t0110-gateway.sh b/test/sharness/t0110-gateway.sh index 032dfccc658..cb0b0cd6743 100755 --- a/test/sharness/t0110-gateway.sh +++ b/test/sharness/t0110-gateway.sh @@ -54,8 +54,9 @@ test_expect_success "GET IPFS path output looks good" ' ' test_expect_success "GET IPFS directory path succeeds" ' - mkdir dir && + mkdir -p dir/dirwithindex && echo "12345" >dir/test && + echo "hello i am a webpage" >dir/dirwithindex/index.html && ipfs add -r -q dir >actual && HASH2=$(tail -n 1 actual) && curl -sf "http://127.0.0.1:$port/ipfs/$HASH2" @@ -69,6 +70,16 @@ test_expect_success "GET IPFS directory file output looks good" ' test_cmp dir/test actual ' +test_expect_success "GET IPFS directory with index.html returns redirect to add trailing slash" " + curl -sI -o response_without_slash \"http://127.0.0.1:$port/ipfs/$HASH2/dirwithindex?query=to-remember\" && + test_should_contain \"Location: /ipfs/$HASH2/dirwithindex/?query=to-remember\" response_without_slash +" + +test_expect_success "GET IPFS directory with index.html and trailing slash returns expected output" " + curl -s -o response_with_slash \"http://127.0.0.1:$port/ipfs/$HASH2/dirwithindex/?query=to-remember\" && + test_should_contain \"hello i am a webpage\" response_with_slash +" + test_expect_success "GET IPFS nonexistent file returns code expected (404)" ' test_curl_resp_http_code "http://127.0.0.1:$port/ipfs/$HASH2/pleaseDontAddMe" "HTTP/1.1 404 Not Found" ' From 91c1aaa1b5a87eefa6ba1da904288de447e62d08 Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Mon, 19 Oct 2020 18:24:13 -0400 Subject: [PATCH 031/116] fix: do not create and print out an unused new peerID when initializing from a config --- cmd/ipfs/daemon.go | 18 +++++++++++------ cmd/ipfs/init.go | 50 ++++++++++++++++++++-------------------------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/daemon.go index 720638acb2e..4fd0a16f71a 100644 --- a/cmd/ipfs/daemon.go +++ b/cmd/ipfs/daemon.go @@ -250,14 +250,20 @@ func daemonFunc(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment } } - identity, err := config.CreateIdentity(os.Stdout, []options.KeyGenerateOption{ - options.Key.Type(algorithmDefault), - }) - if err != nil { - return err + if conf == nil { + identity, err := config.CreateIdentity(os.Stdout, []options.KeyGenerateOption{ + options.Key.Type(algorithmDefault), + }) + if err != nil { + return err + } + conf, err = config.InitWithIdentity(identity) + if err != nil { + return err + } } - if err = doInit(os.Stdout, cctx.ConfigRoot, false, &identity, profiles, conf); err != nil { + if err = doInit(os.Stdout, cctx.ConfigRoot, false, profiles, conf); err != nil { return err } } diff --git a/cmd/ipfs/init.go b/cmd/ipfs/init.go index a039583a203..0842b71976d 100644 --- a/cmd/ipfs/init.go +++ b/cmd/ipfs/init.go @@ -113,24 +113,30 @@ environment variable: } } - var err error - var identity config.Identity - if nBitsGiven { - identity, err = config.CreateIdentity(os.Stdout, []options.KeyGenerateOption{ - options.Key.Size(nBitsForKeypair), - options.Key.Type(algorithm), - }) - } else { - identity, err = config.CreateIdentity(os.Stdout, []options.KeyGenerateOption{ - options.Key.Type(algorithm), - }) - } - if err != nil { - return err + if conf == nil { + var err error + var identity config.Identity + if nBitsGiven { + identity, err = config.CreateIdentity(os.Stdout, []options.KeyGenerateOption{ + options.Key.Size(nBitsForKeypair), + options.Key.Type(algorithm), + }) + } else { + identity, err = config.CreateIdentity(os.Stdout, []options.KeyGenerateOption{ + options.Key.Type(algorithm), + }) + } + if err != nil { + return err + } + conf, err = config.InitWithIdentity(identity) + if err != nil { + return err + } } profiles, _ := req.Options[profileOptionName].(string) - return doInit(os.Stdout, cctx.ConfigRoot, empty, &identity, profiles, conf) + return doInit(os.Stdout, cctx.ConfigRoot, empty, profiles, conf) }, } @@ -152,7 +158,7 @@ func applyProfiles(conf *config.Config, profiles string) error { return nil } -func doInit(out io.Writer, repoRoot string, empty bool, identity *config.Identity, confProfiles string, conf *config.Config) error { +func doInit(out io.Writer, repoRoot string, empty bool, confProfiles string, conf *config.Config) error { if _, err := fmt.Fprintf(out, "initializing IPFS node at %s\n", repoRoot); err != nil { return err } @@ -165,18 +171,6 @@ func doInit(out io.Writer, repoRoot string, empty bool, identity *config.Identit return errRepoExists } - if identity == nil { - return fmt.Errorf("No Identity provided for initialization") - } - - if conf == nil { - var err error - conf, err = config.InitWithIdentity(*identity) - if err != nil { - return err - } - } - if err := applyProfiles(conf, confProfiles); err != nil { return err } From d1c20bdff75d96a72ee0fe004c01a606df933c23 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Tue, 20 Oct 2020 00:40:46 +0200 Subject: [PATCH 032/116] fix: localhost API access via ipv6 This adds localhost ipv6 addresses to the allowlist for use in browser context and fixes WebUI on ipv6-only deployments: http://[::1]:5001/webui We were missing CORS/Origin tests for API port so I've added basic ones and included localhost/127.0.0.1/::1 variants. --- core/corehttp/commands.go | 2 + test/sharness/t0112-gateway-cors.sh | 7 -- ...pi-security.sh => t0400-api-no-gateway.sh} | 0 test/sharness/t0401-api-browser-security.sh | 69 +++++++++++++++++++ 4 files changed, 71 insertions(+), 7 deletions(-) rename test/sharness/{t0400-api-security.sh => t0400-api-no-gateway.sh} (100%) create mode 100755 test/sharness/t0401-api-browser-security.sh diff --git a/core/corehttp/commands.go b/core/corehttp/commands.go index 0f9b8d60309..c5443f6eb3f 100644 --- a/core/corehttp/commands.go +++ b/core/corehttp/commands.go @@ -40,6 +40,8 @@ const APIPath = "/api/v0" var defaultLocalhostOrigins = []string{ "http://127.0.0.1:", "https://127.0.0.1:", + "http://[::1]:", + "https://[::1]:", "http://localhost:", "https://localhost:", } diff --git a/test/sharness/t0112-gateway-cors.sh b/test/sharness/t0112-gateway-cors.sh index c7c5c3e40c6..9670b7ffa16 100755 --- a/test/sharness/t0112-gateway-cors.sh +++ b/test/sharness/t0112-gateway-cors.sh @@ -6,16 +6,9 @@ test_description="Test HTTP Gateway CORS Support" -test_config_ipfs_cors_headers() { - ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '["*"]' - ipfs config --json API.HTTPHeaders.Access-Control-Allow-Methods '["PUT", "GET", "POST"]' - ipfs config --json API.HTTPHeaders.Access-Control-Allow-Headers '["X-Requested-With"]' -} - . lib/test-lib.sh test_init_ipfs -test_config_ipfs_cors_headers test_launch_ipfs_daemon thash='QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn' diff --git a/test/sharness/t0400-api-security.sh b/test/sharness/t0400-api-no-gateway.sh similarity index 100% rename from test/sharness/t0400-api-security.sh rename to test/sharness/t0400-api-no-gateway.sh diff --git a/test/sharness/t0401-api-browser-security.sh b/test/sharness/t0401-api-browser-security.sh new file mode 100755 index 00000000000..1e36bcead32 --- /dev/null +++ b/test/sharness/t0401-api-browser-security.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2020 Protocol Labs +# MIT Licensed; see the LICENSE file in this repository. +# + +test_description="Test API browser security" + +. lib/test-lib.sh + +test_init_ipfs + +PEERID=$(ipfs config Identity.PeerID) + +test_launch_ipfs_daemon + +test_expect_success "browser is unable to access API without Origin" ' + curl -sD - -X POST -A "Mozilla" "http://127.0.0.1:$API_PORT/api/v0/id" >curl_output && + grep "HTTP/1.1 403 Forbidden" curl_output +' + +test_expect_success "browser is unable to access API with invalid Origin" ' + curl -sD - -X POST -A "Mozilla" -H "Origin: https://invalid.example.com" "http://127.0.0.1:$API_PORT/api/v0/id" >curl_output && + grep "HTTP/1.1 403 Forbidden" curl_output +' + +test_expect_success "browser is able to access API if Origin is the API port on localhost (ipv4)" ' + curl -sD - -X POST -A "Mozilla" -H "Origin: http://127.0.0.1:$API_PORT" "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_expect_success "browser is able to access API if Origin is the API port on localhost (ipv6)" ' + curl -sD - -X POST -A "Mozilla" -H "Origin: http://[::1]:$API_PORT" "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_expect_success "browser is able to access API if Origin is the API port on localhost (localhost name)" ' + curl -sD - -X POST -A "Mozilla" -H "Origin: http://localhost:$API_PORT" "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" " + ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '[\"https://valid.example.com\"]' && + ipfs config --json API.HTTPHeaders.Access-Control-Allow-Methods '[\"POST\"]' && + ipfs config --json API.HTTPHeaders.Access-Control-Allow-Headers '[\"X-Requested-With\"]' +" + +test_launch_ipfs_daemon + +# 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 && + cat curl_output +' + +# OPTION Response from Gateway should contain CORS headers, otherwise JS won't work +test_expect_success "OPTIONS response for API with CORS allowslist looks good" ' + grep "< Access-Control-Allow-Origin: https://valid.example.com" curl_output +' + +test_expect_success "browser is able to access API with valid Origin matching CORS allowlist" ' + curl -sD - -X POST -A "Mozilla" -H "Origin: https://valid.example.com" "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_done From 02733f7355376e7ba86aaf1a3f09b3f8dcea531d Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Fri, 23 Oct 2020 17:29:47 -0400 Subject: [PATCH 033/116] fix: return an error when trying to fetch fs-repo-migrations for linux + musl --- repo/fsrepo/migrations/migrations.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/repo/fsrepo/migrations/migrations.go b/repo/fsrepo/migrations/migrations.go index b099216217c..186d4a10dc0 100644 --- a/repo/fsrepo/migrations/migrations.go +++ b/repo/fsrepo/migrations/migrations.go @@ -220,6 +220,11 @@ func GetBinaryForVersion(distname, binnom, root, vers, out string) error { if err != nil { return err } + + if osv == "linux-musl" { + return fmt.Errorf("linux-musl not supported, you must build the binary from source for your platform") + } + finame := fmt.Sprintf("%s_%s_%s-%s.%s", distname, vers, osv, runtime.GOARCH, archive) distpath := fmt.Sprintf("%s/%s/%s/%s", root, distname, vers, finame) From 9c5304a21de66fa8f1eae715e8218396b31d18d6 Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Wed, 4 Nov 2020 21:14:00 -0500 Subject: [PATCH 034/116] fix: ipfs dag export uses the CoreAPI and respects the offline flag --- core/commands/dag/dag.go | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/core/commands/dag/dag.go b/core/commands/dag/dag.go index 24e40d83059..42bd3fe71c4 100644 --- a/core/commands/dag/dag.go +++ b/core/commands/dag/dag.go @@ -550,7 +550,7 @@ The output of blocks happens in strict DAG-traversal, first-seen, order. ) } - node, err := cmdenv.GetNode(env) + api, err := cmdenv.GetApi(env, req) if err != nil { return err } @@ -588,7 +588,7 @@ The output of blocks happens in strict DAG-traversal, first-seen, order. req.Context, mdag.NewSession( req.Context, - node.DAG, + api.Dag(), ), []cid.Cid{c}, pipeW, @@ -606,9 +606,16 @@ The output of blocks happens in strict DAG-traversal, first-seen, order. // minimal user friendliness if err != nil && - !node.IsOnline && err == ipld.ErrNotFound { - err = fmt.Errorf("%s (currently offline, perhaps retry after attaching to the network)", err) + explicitOffline, _ := req.Options["offline"].(bool) + if explicitOffline { + err = fmt.Errorf("%s (currently offline, perhaps retry without the offline flag)", err) + } else { + node, envErr := cmdenv.GetNode(env) + if envErr == nil && !node.IsOnline { + err = fmt.Errorf("%s (currently offline, perhaps retry after attaching to the network)", err) + } + } } return err From d4cd378092755ab67d07f33137996a47bb31dcbb Mon Sep 17 00:00:00 2001 From: Chaitanya Date: Sat, 7 Nov 2020 12:24:18 +0530 Subject: [PATCH 035/116] Clarify why ipfs file ls is being deprecated. --- core/commands/unixfs/ls.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/commands/unixfs/ls.go b/core/commands/unixfs/ls.go index 58c57797b70..39531bc1a0e 100644 --- a/core/commands/unixfs/ls.go +++ b/core/commands/unixfs/ls.go @@ -34,7 +34,7 @@ type LsOutput struct { var LsCmd = &cmds.Command{ Helptext: cmds.HelpText{ - Tagline: "List directory contents for Unix filesystem objects.", + Tagline: "List directory contents for Unix filesystem objects. Deprecated: Use 'ipfs ls' instead", ShortDescription: ` Displays the contents of an IPFS or IPNS object(s) at the given path. @@ -44,6 +44,8 @@ size is the IPFS link size. This functionality is deprecated, and will be removed in future versions. If possible, please use 'ipfs ls' instead. + +It is deprecated because 'ipfs file ls' drop some of the ipfs specific info and almost same as 'ipfs ls' `, LongDescription: ` Displays the contents of an IPFS or IPNS object(s) at the given path. @@ -64,6 +66,8 @@ Example: This functionality is deprecated, and will be removed in future versions. If possible, please use 'ipfs ls' instead. + +It is deprecated because 'ipfs file ls' drop some of the ipfs specific info and almost same as 'ipfs ls' `, }, From c6fe39a4a5151a4961d8f8107d913c7a503c5eb0 Mon Sep 17 00:00:00 2001 From: Chaitanya Raju Date: Sat, 7 Nov 2020 12:51:01 +0530 Subject: [PATCH 036/116] Explain that ipfs ls works on IPFS paths, and ipfs files ls works on both IPFS paths and MFS paths. --- core/commands/files.go | 4 ++-- core/commands/ls.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/commands/files.go b/core/commands/files.go index ab55545557f..28ea69634aa 100644 --- a/core/commands/files.go +++ b/core/commands/files.go @@ -417,9 +417,9 @@ const ( var filesLsCmd = &cmds.Command{ Helptext: cmds.HelpText{ - Tagline: "List directories in the local mutable namespace.", + Tagline: "List directories in the local mutable namespace. (Both IPFS and MFS paths)", ShortDescription: ` -List directories in the local mutable namespace. +List directories in the local mutable namespace (Both IPFS and MFS paths). Examples: diff --git a/core/commands/ls.go b/core/commands/ls.go index 4b0114d3341..e635184b624 100644 --- a/core/commands/ls.go +++ b/core/commands/ls.go @@ -47,7 +47,7 @@ const ( var LsCmd = &cmds.Command{ Helptext: cmds.HelpText{ - Tagline: "List directory contents for Unix filesystem objects.", + Tagline: "List directory contents for Unix filesystem objects. (Only IPFS paths)", ShortDescription: ` Displays the contents of an IPFS or IPNS object(s) at the given path, with the following format: From 2539c7617799358e858d9571754e7c30c72285a3 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Tue, 10 Nov 2020 21:25:14 +0100 Subject: [PATCH 037/116] docs(readme): key rotation in docker (#7721) * docs(readme): key rotation in docker Adds notes from https://github.com/ipfs/go-ipfs/issues/7714#issuecomment-706319721 --- README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/README.md b/README.md index 86d9205b911..f0f7b1510f6 100644 --- a/README.md +++ b/README.md @@ -378,6 +378,8 @@ When starting a container running ipfs for the first time with an empty data dir docker run -d --name ipfs_host -e IPFS_PROFILE=server -v $ipfs_staging:/export -v $ipfs_data:/data/ipfs -p 4001:4001 -p 4001:4001/udp -p 127.0.0.1:8080:8080 -p 127.0.0.1:5001:5001 ipfs/go-ipfs:latest +#### Private swarms inside Docker + It is possible to initialize the container with a swarm key file (`/data/ipfs/swarm.key`) using the variables `IPFS_SWARM_KEY` and `IPFS_SWARM_KEY_FILE`. The `IPFS_SWARM_KEY` creates `swarm.key` with the contents of the variable itself, whilst `IPFS_SWARM_KEY_FILE` copies the key from a path stored in the variable. The `IPFS_SWARM_KEY_FILE` **overwrites** the key generated by `IPFS_SWARM_KEY`. docker run -d --name ipfs_host -e IPFS_SWARM_KEY= -v $ipfs_staging:/export -v $ipfs_data:/data/ipfs -p 4001:4001 -p 4001:4001/udp -p 127.0.0.1:8080:8080 -p 127.0.0.1:5001:5001 ipfs/go-ipfs:latest @@ -387,6 +389,20 @@ The swarm key initialization can also be done using docker secrets **(requires d cat your_swarm.key | docker secret create swarm_key_secret - docker run -d --name ipfs_host --secret swarm_key_secret -e IPFS_SWARM_KEY_FILE=/run/secrets/swarm_key_secret -v $ipfs_staging:/export -v $ipfs_data:/data/ipfs -p 4001:4001 -p 4001:4001/udp -p 127.0.0.1:8080:8080 -p 127.0.0.1:5001:5001 ipfs/go-ipfs:latest +#### Key rotation inside Docker + +If needed, it is possible to do key rotation in an ephemeral container that is temporarily executing against a volume that is mounted under `/data/ipfs`: + +```sh +# given container named 'ipfs-test' that persists repo at /path/to/persisted/.ipfs +$ docker run -d --name ipfs-test -v /path/to/persisted/.ipfs:/data/ipfs ipfs/go-ipfs:v0.7.0 +$ docker stop ipfs-test + +# key rotation works like this (old key saved under 'old-self') +$ docker run --rm -it -v /path/to/persisted/.ipfs:/data/ipfs ipfs/go-ipfs:v0.7.0 key rotate -o old-self -t ed25519 +$ docker start ipfs-test # will start with the new key +``` + ### Troubleshooting If you have previously installed IPFS before and you are running into problems getting a newer version to work, try deleting (or backing up somewhere else) your IPFS config directory (~/.ipfs by default) and rerunning `ipfs init`. This will reinitialize the config file to its defaults and clear out the local datastore of any bad entries. From 37a637e8c1d7ca867a8d23e035418efb9b736fc9 Mon Sep 17 00:00:00 2001 From: Andrew Nesbitt Date: Wed, 11 Nov 2020 13:04:52 +0000 Subject: [PATCH 038/116] Fix typo in ipfs dag stat command --- core/commands/dag/dag.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/commands/dag/dag.go b/core/commands/dag/dag.go index 24e40d83059..72379000b9b 100644 --- a/core/commands/dag/dag.go +++ b/core/commands/dag/dag.go @@ -685,7 +685,7 @@ var DagStatCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Gets stats for a DAG", ShortDescription: ` -'ipfs dag size' fetches a dag and returns various statistics about the DAG. +'ipfs dag stat' fetches a dag and returns various statistics about the DAG. Statistics include size and number of blocks. Note: This command skips duplicate blocks in reporting both size and the number of blocks From 5cd013ed380cb29a4bff75874a3a4ee5d30fd747 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 2 Nov 2020 11:46:32 -0800 Subject: [PATCH 039/116] update libp2p for stream closure refactor --- core/coreapi/pubsub.go | 6 +- go.mod | 37 +++++----- go.sum | 154 +++++++++++++++++++++++------------------ 3 files changed, 111 insertions(+), 86 deletions(-) diff --git a/core/coreapi/pubsub.go b/core/coreapi/pubsub.go index e84d1503481..a75db36296b 100644 --- a/core/coreapi/pubsub.go +++ b/core/coreapi/pubsub.go @@ -118,5 +118,9 @@ func (msg *pubSubMessage) Seq() []byte { } func (msg *pubSubMessage) Topics() []string { - return msg.msg.TopicIDs + // TODO: handle breaking downstream changes by returning a single string. + if msg.msg.Topic == nil { + return nil + } + return []string{*msg.msg.Topic} } diff --git a/go.mod b/go.mod index 21081465235..9e19a7a5077 100644 --- a/go.mod +++ b/go.mod @@ -14,9 +14,9 @@ require ( github.com/gogo/protobuf v1.3.1 github.com/hashicorp/go-multierror v1.1.0 github.com/hashicorp/golang-lru v0.5.4 - github.com/ipfs/go-bitswap v0.2.20 + github.com/ipfs/go-bitswap v0.3.2 github.com/ipfs/go-block-format v0.0.2 - github.com/ipfs/go-blockservice v0.1.3 + github.com/ipfs/go-blockservice v0.1.4 github.com/ipfs/go-cid v0.0.7 github.com/ipfs/go-cidutil v0.0.2 github.com/ipfs/go-datastore v0.4.5 @@ -27,7 +27,7 @@ require ( github.com/ipfs/go-ds-measure v0.1.0 github.com/ipfs/go-filestore v0.0.3 github.com/ipfs/go-fs-lock v0.0.6 - github.com/ipfs/go-graphsync v0.1.1 + github.com/ipfs/go-graphsync v0.5.0 github.com/ipfs/go-ipfs-blockstore v0.1.4 github.com/ipfs/go-ipfs-chunker v0.0.5 github.com/ipfs/go-ipfs-cmds v0.4.0 @@ -54,33 +54,33 @@ require ( github.com/ipfs/go-unixfs v0.2.4 github.com/ipfs/go-verifcid v0.0.1 github.com/ipfs/interface-go-ipfs-core v0.4.0 - github.com/ipld/go-car v0.1.1-0.20200429200904-c222d793c339 + github.com/ipld/go-car v0.1.1-0.20201015032735-ff6ccdc46acc github.com/jbenet/go-is-domain v1.0.5 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-libp2p v0.11.0 - github.com/libp2p/go-libp2p-circuit v0.3.1 + github.com/libp2p/go-libp2p v0.12.0 + github.com/libp2p/go-libp2p-circuit v0.4.0 github.com/libp2p/go-libp2p-connmgr v0.2.4 - github.com/libp2p/go-libp2p-core v0.6.1 + github.com/libp2p/go-libp2p-core v0.7.0 github.com/libp2p/go-libp2p-discovery v0.5.0 - github.com/libp2p/go-libp2p-http v0.1.5 - github.com/libp2p/go-libp2p-kad-dht v0.9.0 + github.com/libp2p/go-libp2p-http v0.2.0 + github.com/libp2p/go-libp2p-kad-dht v0.11.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.2.4 + github.com/libp2p/go-libp2p-mplex v0.3.0 github.com/libp2p/go-libp2p-noise v0.1.1 github.com/libp2p/go-libp2p-peerstore v0.2.6 - github.com/libp2p/go-libp2p-pubsub v0.3.5 - github.com/libp2p/go-libp2p-pubsub-router v0.3.2 - github.com/libp2p/go-libp2p-quic-transport v0.8.2 + github.com/libp2p/go-libp2p-pubsub v0.4.0 + github.com/libp2p/go-libp2p-pubsub-router v0.4.0 + github.com/libp2p/go-libp2p-quic-transport v0.9.0 github.com/libp2p/go-libp2p-record v0.1.3 github.com/libp2p/go-libp2p-routing-helpers v0.2.3 github.com/libp2p/go-libp2p-secio v0.2.2 - github.com/libp2p/go-libp2p-swarm v0.2.8 - github.com/libp2p/go-libp2p-testing v0.2.0 + github.com/libp2p/go-libp2p-swarm v0.3.1 + github.com/libp2p/go-libp2p-testing v0.3.0 github.com/libp2p/go-libp2p-tls v0.1.3 - github.com/libp2p/go-libp2p-yamux v0.2.8 + github.com/libp2p/go-libp2p-yamux v0.4.0 github.com/libp2p/go-socket-activation v0.0.2 github.com/libp2p/go-tcp-transport v0.2.1 github.com/libp2p/go-ws-transport v0.3.1 @@ -101,11 +101,10 @@ require ( github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 github.com/whyrusleeping/tar-utils v0.0.0-20180509141711-8c6c8ba81d5c go.uber.org/fx v1.13.1 - go.uber.org/zap v1.15.0 - golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 + go.uber.org/zap v1.16.0 + golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 - golang.org/x/tools v0.0.0-20200522201501-cb1345f3a375 // indirect ) go 1.13 diff --git a/go.sum b/go.sum index 4ed782816aa..0597eb9acc6 100644 --- a/go.sum +++ b/go.sum @@ -91,6 +91,7 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR 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/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/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= @@ -104,6 +105,7 @@ github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+ github.com/coreos/go-systemd/v22 v22.1.0 h1:kq/SbG2BCKLkDKkjQf5OWwKWUKj1lgs3lFI4PxnR5lg= github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= 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/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/cskr/pubsub v1.0.2 h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0= @@ -132,7 +134,9 @@ github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4 github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= 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.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/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= @@ -199,6 +203,7 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0 h1:oOuy+ugB+P/kBdUnG5QaMXSIyJ1q38wWSojYCb3z5VQ= 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 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w= @@ -212,6 +217,8 @@ github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 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= @@ -226,6 +233,8 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= 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 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= +github.com/google/uuid v1.1.2/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= @@ -245,6 +254,7 @@ github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpg 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/gxed/pubsub v0.0.0-20180201040156-26ebdf44f824/go.mod h1:OiEWyHgK+CWrmOlVquHaIK1vhpUJydC9m0Je6mhaiNE= +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/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= @@ -273,8 +283,8 @@ 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.3/go.mod h1:YEQlFy0kkxops5Vy+OxWdRSEZIoS7I7KDIwoa5Chkps= github.com/ipfs/go-bitswap v0.1.8/go.mod h1:TOWoxllhccevbWFUR2N7B1MTSVVge1s6XSMiCSA4MzM= -github.com/ipfs/go-bitswap v0.2.20 h1:Zfi5jDUoqxDThORUznqdeL77DdGniAzlccNJ4vr+Itc= -github.com/ipfs/go-bitswap v0.2.20/go.mod h1:C7TwBgHnu89Q8sHsTJP7IhUqF9XYLe71P4tT5adgmYo= +github.com/ipfs/go-bitswap v0.3.2 h1:TdKx7lpidYe2dMAKfdeNS26y6Pc/AZX/i8doI1GV210= +github.com/ipfs/go-bitswap v0.3.2/go.mod h1:AyWWfN3moBzQX0banEtfKOfbXb3ZeoOeXnZGNPV9S6w= 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= @@ -286,6 +296,8 @@ github.com/ipfs/go-blockservice v0.1.2 h1:fqFeeu1EG0lGVrqUo+BVJv7LZV31I4ZsyNthCO github.com/ipfs/go-blockservice v0.1.2/go.mod h1:t+411r7psEUhLueM8C7aPA7cxCclv4O3VsUVxt9kz2I= 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.1.4 h1:Vq+MlsH8000KbbUciRyYMEw/NNP8UAGmcqKi4uWmFGA= +github.com/ipfs/go-blockservice v0.1.4/go.mod h1:OTZhFpkgY48kNzbgyvcexW9cHrpjBYIjSR0KoDOFOLU= 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 h1:UIAh32wymBpStoe83YCzwVQQ5Oy/H0FdxvUS6DJDzms= @@ -343,8 +355,8 @@ github.com/ipfs/go-filestore v0.0.3 h1:MhZ1jT5K3NewZwim6rS/akcJLm1xM+r6nz6foeB9E github.com/ipfs/go-filestore v0.0.3/go.mod h1:dvXRykFzyyXN2CdNlRGzDAkXMDPyI+D7JE066SiKLSE= github.com/ipfs/go-fs-lock v0.0.6 h1:sn3TWwNVQqSeNjlWy6zQ1uUGAZrV3hPOyEA6y1/N2a0= github.com/ipfs/go-fs-lock v0.0.6/go.mod h1:OTR+Rj9sHiRubJh3dRhD15Juhd/+w6VPOY28L7zESmM= -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-graphsync v0.5.0 h1:iaByvxq88Ys1KcaQzTS1wmRhNsNEo3SaUiSGqTSbGmM= +github.com/ipfs/go-graphsync v0.5.0/go.mod h1:e2ZxnClqBBYAtd901g9vXMJzS47labjAtOzsWtOzKNk= github.com/ipfs/go-ipfs-blockstore v0.0.1/go.mod h1:d3WClOmRQKFnJ0Jz/jj/zmksX0ma1gROTlovZKBmN08= github.com/ipfs/go-ipfs-blockstore v0.1.0 h1:V1GZorHFUIB6YgTJQdq7mcaIpUfCM3fCyVi+MTo9O88= github.com/ipfs/go-ipfs-blockstore v0.1.0/go.mod h1:5aD0AvHPi7mZc6Ci1WCAhiBQu2IsfTduLl+422H6Rqw= @@ -464,12 +476,14 @@ github.com/ipfs/interface-go-ipfs-core v0.3.0 h1:oZdLLfh256gPGcYPURjivj/lv296GIc github.com/ipfs/interface-go-ipfs-core v0.3.0/go.mod h1:Tihp8zxGpUeE3Tokr94L6zWZZdkRQvG5TL6i9MuNE+s= 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/ipld/go-car v0.1.1-0.20200429200904-c222d793c339 h1:YEYaf6mrrjoTfGpi7MajslcGvhP23Sh0b3ubcGYRMw0= -github.com/ipld/go-car v0.1.1-0.20200429200904-c222d793c339/go.mod h1:eajxljm6I8o3LitnFeVEmucwZmz7+yLSiKce9yYMefg= -github.com/ipld/go-ipld-prime v0.0.2-0.20200428162820-8b59dc292b8e h1:ZISbJlM0urTANR9KRfRaqlBmyOj5uUtxs2r4Up9IXsA= -github.com/ipld/go-ipld-prime v0.0.2-0.20200428162820-8b59dc292b8e/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-car v0.1.1-0.20201015032735-ff6ccdc46acc h1:BdI33Q56hLWG9Ef0WbQ7z+dwmbRYhTb45SMjw0RudbQ= +github.com/ipld/go-car v0.1.1-0.20201015032735-ff6ccdc46acc/go.mod h1:WdIgzcEjFqydQ7jH+BXzGYxVCmLeAs5nP8Vu3Rege2Y= +github.com/ipld/go-ipld-prime v0.5.1-0.20200828233916-988837377a7f/go.mod h1:0xEgdD6MKbZ1vF0GC+YcR/C4SQCAlRuOjIJ2i0HxqzM= +github.com/ipld/go-ipld-prime v0.5.1-0.20201021195245-109253e8a018 h1:RbRHv8epkmvBYA5cGfz68GUSbOgx5j/7ObLIl4Rsif0= +github.com/ipld/go-ipld-prime v0.5.1-0.20201021195245-109253e8a018/go.mod h1:0xEgdD6MKbZ1vF0GC+YcR/C4SQCAlRuOjIJ2i0HxqzM= +github.com/ipld/go-ipld-prime-proto v0.0.0-20200922192210-9a2bfd4440a6/go.mod h1:3pHYooM9Ea65jewRwrb2u5uHZCNkNTe9ABsVB+SrkH0= +github.com/ipld/go-ipld-prime-proto v0.1.0 h1:j7gjqrfwbT4+gXpHwEx5iMssma3mnctC7YaCimsFP70= +github.com/ipld/go-ipld-prime-proto v0.1.0/go.mod h1:11zp8f3sHVgIqtb/c9Kr5ZGqpnCLF1IVTNOez9TopzE= github.com/jackpal/gateway v1.0.4/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQetPfnjA= github.com/jackpal/gateway v1.0.5 h1:qzXWUJfuMdlLMtt0a3Dgt+xkWQiA5itDEITVJtuSwMc= github.com/jackpal/gateway v1.0.5/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQetPfnjA= @@ -555,8 +569,6 @@ github.com/libp2p/go-libp2p v0.0.2/go.mod h1:Qu8bWqFXiocPloabFGUcVG4kk94fLvfC8mW 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.6.0 h1:EFArryT9N7AVA70LCcOh8zxsW+FeDnxwcpWQx9k7+GM= -github.com/libp2p/go-libp2p v0.6.0/go.mod h1:mfKWI7Soz3ABX+XEBR61lGbg+ewyMtJHVt043oWeqwg= github.com/libp2p/go-libp2p v0.6.1 h1:mxabyJf4l6AmotDOKObwSfBNBWjL5VYXysVFLUMAuB8= github.com/libp2p/go-libp2p v0.6.1/go.mod h1:CTFnWXogryAHjXAKEbOf1OWY+VeAP3lDMZkfEI5sT54= github.com/libp2p/go-libp2p v0.7.0 h1:qWmciout2lJclKfRlxqdepsQB7JihcbRhgcRcssP4rc= @@ -564,10 +576,8 @@ github.com/libp2p/go-libp2p v0.7.0/go.mod h1:hZJf8txWeCduQRDC/WSqBGMxaTHCOYHt2xS github.com/libp2p/go-libp2p v0.7.4 h1:xVj1oSlN0C+FlxqiLuHC8WruMvq24xxfeVxmNhTG0r0= github.com/libp2p/go-libp2p v0.7.4/go.mod h1:oXsBlTLF1q7pxr+9w6lqzS1ILpyHsaBPniVO7zIHGMw= github.com/libp2p/go-libp2p v0.8.1/go.mod h1:QRNH9pwdbEBpx5DTJYg+qxcVaDMAz3Ee/qDKwXujH5o= -github.com/libp2p/go-libp2p v0.8.3 h1:IFWeNzxkBaNO1N8stN9ayFGdC6RmVuSsKd5bou7qpK0= -github.com/libp2p/go-libp2p v0.8.3/go.mod h1:EsH1A+8yoWK+L4iKcbPYu6MPluZ+CHWI9El8cTaefiM= -github.com/libp2p/go-libp2p v0.11.0 h1:jb5mqdqYEBAybTEhD8io43Cz5LzVKuWxOK7znSN69jE= -github.com/libp2p/go-libp2p v0.11.0/go.mod h1:3/ogJDXsbbepEfqtZKBR/DedzxJXCeK17t2Z9RE9bEE= +github.com/libp2p/go-libp2p v0.12.0 h1:+xai9RQnQ9l5elFOKvp5wRyjyWisSwEx+6nU2+onpUA= +github.com/libp2p/go-libp2p v0.12.0/go.mod h1:FpHZrfC1q7nA8jitvdjKBDF31hguaC676g/nT9PgQM0= github.com/libp2p/go-libp2p-asn-util v0.0.0-20200825225859-85005c6cf052 h1:BM7aaOF7RpmNn9+9g6uTjGJ0cTzWr5j9i9IKeun2M8U= 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-autonat v0.0.2/go.mod h1:fs71q5Xk+pdnKU014o2iq1RhMs9/PMaG5zXRFNnIIT4= @@ -582,14 +592,12 @@ github.com/libp2p/go-libp2p-autonat v0.2.1 h1:T0CRQhrvTBKfBSYw6Xo2K3ixtNpAnRCrax github.com/libp2p/go-libp2p-autonat v0.2.1/go.mod h1:MWtAhV5Ko1l6QBsHQNSuM6b1sRkXrpk0/LqCr+vCVxI= github.com/libp2p/go-libp2p-autonat v0.2.2 h1:4dlgcEEugTFWSvdG2UIFxhnOMpX76QaZSRAtXmYB8n4= github.com/libp2p/go-libp2p-autonat v0.2.2/go.mod h1:HsM62HkqZmHR2k1xgX34WuWDzk/nBwNHoeyyT4IWV6A= -github.com/libp2p/go-libp2p-autonat v0.3.2 h1:OhDSwVVaq7liTaRIsFFYvsaPp0pn2yi0WazejZ4DUmo= -github.com/libp2p/go-libp2p-autonat v0.3.2/go.mod h1:0OzOi1/cVc7UcxfOddemYD5vzEqi4fwRbnZcJGLi68U= +github.com/libp2p/go-libp2p-autonat v0.4.0 h1:3y8XQbpr+ssX8QfZUHekjHCYK64sj6/4hnf/awD4+Ug= +github.com/libp2p/go-libp2p-autonat v0.4.0/go.mod h1:YxaJlpr81FhdOv3W3BTconZPfhaYivRdf53g+S2wobk= 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 h1:I96SWjR4rK9irDHcHq3XHN6hawCRTPUADzkJacgZLvk= 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 h1:3EsGAi0CBGcZ33GwRuXEYJLLPoVWyXJ1bcJzAJjINkk= github.com/libp2p/go-libp2p-blankhost v0.2.0/go.mod h1:eduNKXGTioTuQAUcZ5epXi9vMl+t4d8ugUBRQ4SqaNQ= github.com/libp2p/go-libp2p-circuit v0.0.1/go.mod h1:Dqm0s/BiV63j8EEAs8hr1H5HudqvCAeXxDyic59lCwE= @@ -599,10 +607,8 @@ github.com/libp2p/go-libp2p-circuit v0.1.4 h1:Phzbmrg3BkVzbqd4ZZ149JxCuUWu2wZcXf github.com/libp2p/go-libp2p-circuit v0.1.4/go.mod h1:CY67BrEjKNDhdTk8UgBX1Y/H5c3xkAcs3gnksxY7osU= github.com/libp2p/go-libp2p-circuit v0.2.1 h1:BDiBcQxX/ZJJ/yDl3sqZt1bjj4PkZCEi7IEpwxXr13k= github.com/libp2p/go-libp2p-circuit v0.2.1/go.mod h1:BXPwYDN5A8z4OEY9sOfr2DUQMLQvKt/6oku45YUmjIo= -github.com/libp2p/go-libp2p-circuit v0.2.2 h1:87RLabJ9lrhoiSDDZyCJ80ZlI5TLJMwfyoGAaWXzWqA= -github.com/libp2p/go-libp2p-circuit v0.2.2/go.mod h1:nkG3iE01tR3FoQ2nMm06IUrCpCyJp1Eo4A1xYdpjfs4= -github.com/libp2p/go-libp2p-circuit v0.3.1 h1:69ENDoGnNN45BNDnBd+8SXSetDuw0eJFcGmOvvtOgBw= -github.com/libp2p/go-libp2p-circuit v0.3.1/go.mod h1:8RMIlivu1+RxhebipJwFDA45DasLx+kkrp4IlJj53F4= +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-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= @@ -624,8 +630,6 @@ github.com/libp2p/go-libp2p-core v0.5.0 h1:FBQ1fpq2Fo/ClyjojVJ5AKXlKhvNc/B6U0O+7 github.com/libp2p/go-libp2p-core v0.5.0/go.mod h1:49XGI+kc38oGVwqSBhDEwytaAxgZasHhFfQKibzTls0= github.com/libp2p/go-libp2p-core v0.5.1 h1:6Cu7WljPQtGY2krBlMoD8L/zH3tMUsCbqNFH7cZwCoI= github.com/libp2p/go-libp2p-core v0.5.1/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt5/a35Sm4upn4Y= -github.com/libp2p/go-libp2p-core v0.5.2 h1:hevsCcdLiazurKBoeNn64aPYTVOPdY4phaEGeLtHOAs= -github.com/libp2p/go-libp2p-core v0.5.2/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt5/a35Sm4upn4Y= github.com/libp2p/go-libp2p-core v0.5.3 h1:b9W3w7AZR2n/YJhG8d0qPFGhGhCWKIvPuJgp4hhc4MM= github.com/libp2p/go-libp2p-core v0.5.3/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt5/a35Sm4upn4Y= github.com/libp2p/go-libp2p-core v0.5.4/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt5/a35Sm4upn4Y= @@ -638,6 +642,8 @@ github.com/libp2p/go-libp2p-core v0.6.0 h1:u03qofNYTBN+yVg08PuAKylZogVf0xcTEeM8s github.com/libp2p/go-libp2p-core v0.6.0/go.mod h1:txwbVEhHEXikXn9gfC7/UDDw7rkxuX0bJvM49Ykaswo= github.com/libp2p/go-libp2p-core v0.6.1 h1:XS+Goh+QegCDojUZp00CaPMfiEADCrLjNZskWE7pvqs= 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 h1:4a0TMjrWNTZlNvcqxZmrMRDi/NQWrhwO2pkTuLSQ/IQ= +github.com/libp2p/go-libp2p-core v0.7.0/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= 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 h1:k9MFy+o2zGDNGsaoZl0MA3iZ75qXxr9OOoAZF+sD5OQ= @@ -650,22 +656,20 @@ github.com/libp2p/go-libp2p-discovery v0.2.0 h1:1p3YSOq7VsgaL+xVHPi8XAmtGyas6D2J github.com/libp2p/go-libp2p-discovery v0.2.0/go.mod h1:s4VGaxYMbw4+4+tsoQTqh7wfxg97AEdo4GYBt6BadWg= github.com/libp2p/go-libp2p-discovery v0.3.0 h1:+JnYBRLzZQtRq0mK3xhyjBwHytLmJXMTZkQfbw+UrGA= 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 h1:Qfl+e5+lfDgwdrXdu4YNCWyEo3fWuP+WgN9mN0iWviQ= github.com/libp2p/go-libp2p-discovery v0.5.0/go.mod h1:+srtPIU9gDaBNu//UHvcdliKBIcr4SfDcm0/PfPJLug= -github.com/libp2p/go-libp2p-gostream v0.2.1 h1:JjA9roGokaR2BgWmaI/3HQu1/+jSbVVDLatQGnVdGjI= -github.com/libp2p/go-libp2p-gostream v0.2.1/go.mod h1:1Mjp3LDmkqICe5tH9yLVNCqFaRTy6OwBvuJV6j1b9Nk= +github.com/libp2p/go-libp2p-gostream v0.3.0 h1:rnas//vRdHYCr7bjraZJISPwZV8OGMjeX5k5fN5Ax44= +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= -github.com/libp2p/go-libp2p-http v0.1.5 h1:FfLnzjlEzV4/6UCXCpPXRYZNoGCfogqCFjd7eF0Jbm8= -github.com/libp2p/go-libp2p-http v0.1.5/go.mod h1:2YfPjsQxUlBGFQl2u461unkQ7ukwiSs7NX2eSslOJiU= +github.com/libp2p/go-libp2p-http v0.2.0 h1:GYeVd+RZzkRa8XFLITqOpcrIQG6KbFLPJqII6HHBHzY= +github.com/libp2p/go-libp2p-http v0.2.0/go.mod h1:GlNKFqDZHe25LVy2CvnZKx75/jLtMaD3VxZV6N39X7E= 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.9.0 h1:AKeFYZvfAa/32Sgm0LrPDxGXB62AUtU8MRqqMobBfUM= -github.com/libp2p/go-libp2p-kad-dht v0.9.0/go.mod h1:LEKcCFHxnvypOPaqZ0m6h0fLQ9Y8t1iZMOg7a0aQDD4= +github.com/libp2p/go-libp2p-kad-dht v0.11.0 h1:ZLhlmDKsFiOkPhTzfEqBrMy/1Tqx+Dk6UgbHM5//IQM= +github.com/libp2p/go-libp2p-kad-dht v0.11.0/go.mod h1:5ojtR2acDPqh/jXf5orWy8YGb8bHQDS+qeDcoscL/PI= 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= github.com/libp2p/go-libp2p-loggables v0.0.1/go.mod h1:lDipDlBNYbpyqyPX/KcoO+eq0sJYEVR2JgOexcivchg= @@ -680,8 +684,8 @@ github.com/libp2p/go-libp2p-mplex v0.2.2 h1:+Ld7YDAfVERQ0E+qqjE7o6fHwKuM0SqTzYiw 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.2.4 h1:XFFXaN4jhqnIuJVjYOR3k6bnRj0mFfJOlIuDVww+4Zo= -github.com/libp2p/go-libp2p-mplex v0.2.4/go.mod h1:mI7iOezdWFOisvUwaYd3IDrJ4oVmgoXK8H331ui39CE= +github.com/libp2p/go-libp2p-mplex v0.3.0 h1:CZyqqKP0BSGQyPLvpRQougbfXaaaJZdGgzhCpJNuNSk= +github.com/libp2p/go-libp2p-mplex v0.3.0/go.mod h1:l9QWxRbbb5/hQMECEb908GbS9Sm2UAR2KFZKUJEynEs= github.com/libp2p/go-libp2p-nat v0.0.2/go.mod h1:QrjXQSD5Dj4IJOdEcjHRkWTSomyxRo6HnUkf/TfQpLQ= github.com/libp2p/go-libp2p-nat v0.0.4 h1:+KXK324yaY701On8a0aGjTnw8467kW3ExKcqW2wwmyw= github.com/libp2p/go-libp2p-nat v0.0.4/go.mod h1:N9Js/zVtAXqaeT99cXgTV9e75KpnWCvVOiGzlcHmBbY= @@ -713,23 +717,18 @@ github.com/libp2p/go-libp2p-peerstore v0.2.1 h1:u+gOfsKgu73ZkGWhvckRm03z9C+iS9Tr github.com/libp2p/go-libp2p-peerstore v0.2.1/go.mod h1:NQxhNjWxf1d4w6PihR8btWIRjwRLBr4TYKfNgrUkOPA= github.com/libp2p/go-libp2p-peerstore v0.2.2 h1:iqc/m03jHn5doXN3+kS6JKvqQRHEltiXljQB85iVHWE= github.com/libp2p/go-libp2p-peerstore v0.2.2/go.mod h1:NQxhNjWxf1d4w6PihR8btWIRjwRLBr4TYKfNgrUkOPA= -github.com/libp2p/go-libp2p-peerstore v0.2.3 h1:MofRq2l3c15vQpEygTetV+zRRrncz+ktiXW7H2EKoEQ= -github.com/libp2p/go-libp2p-peerstore v0.2.3/go.mod h1:K8ljLdFn590GMttg/luh4caB/3g0vKuY01psze0upRw= -github.com/libp2p/go-libp2p-peerstore v0.2.4 h1:jU9S4jYN30kdzTpDAR7SlHUD+meDUjTODh4waLWF1ws= -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-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.3.2/go.mod h1:Uss7/Cfz872KggNb+doCVPHeCDmXB7z500m/R8DaAUk= -github.com/libp2p/go-libp2p-pubsub v0.3.5 h1:iF75GWpcxKEUQU8tTkgLy69qIQvfhL+t6U6ndQrB6ho= -github.com/libp2p/go-libp2p-pubsub v0.3.5/go.mod h1:DTMSVmZZfXodB/pvdTGrY2eHPZ9W2ev7hzTH83OKHrI= -github.com/libp2p/go-libp2p-pubsub-router v0.3.2 h1:BGC4irCUXlwmlCSxnA2DVDNY8JqhfAUUaiq3CZvcddw= -github.com/libp2p/go-libp2p-pubsub-router v0.3.2/go.mod h1:G4MAvYzPxhoR0LEBluS9Ow+Nnr/8iDalUN+RNwVgNkY= -github.com/libp2p/go-libp2p-quic-transport v0.8.2 h1:FDaXBCBJ1e5hY6gnWEJ4NbYyLk8eezr4J6AY3q3KqwM= -github.com/libp2p/go-libp2p-quic-transport v0.8.2/go.mod h1:L+e0q15ZNaYm3seHgbsXjWP8kXLEqz+elLWKk9l8DhM= +github.com/libp2p/go-libp2p-pubsub v0.4.0 h1:YNVRyXqBgv9i4RG88jzoTtkSOaSB45CqHkL29NNBZb4= +github.com/libp2p/go-libp2p-pubsub v0.4.0/go.mod h1:izkeMLvz6Ht8yAISXjx60XUQZMq9ZMe5h2ih4dLIBIQ= +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-quic-transport v0.9.0 h1:WPuq5nV/chmIZIzvrkC2ulSdAQ0P0BDvgvAhZFOZ59E= +github.com/libp2p/go-libp2p-quic-transport v0.9.0/go.mod h1:xyY+IgxL0qsW7Kiutab0+NlxM0/p9yRtrGTYsuMWf70= 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= @@ -756,10 +755,11 @@ github.com/libp2p/go-libp2p-swarm v0.2.2 h1:T4hUpgEs2r371PweU3DuH7EOmBIdTBCwWs+F github.com/libp2p/go-libp2p-swarm v0.2.2/go.mod h1:fvmtQ0T1nErXym1/aa1uJEyN7JzaTNyBcHImCxRpPKU= github.com/libp2p/go-libp2p-swarm v0.2.3 h1:uVkCb8Blfg7HQ/f30TyHn1g/uCwXsAET7pU0U59gx/A= github.com/libp2p/go-libp2p-swarm v0.2.3/go.mod h1:P2VO/EpxRyDxtChXz/VPVXyTnszHvokHKRhfkEgFKNM= -github.com/libp2p/go-libp2p-swarm v0.2.4 h1:94XL76/tFeTdJNcIGugi+1uZo5O/a7y4i21PirwbgZI= -github.com/libp2p/go-libp2p-swarm v0.2.4/go.mod h1:/xIpHFPPh3wmSthtxdGbkHZ0OET1h/GGZes8Wku/M5Y= github.com/libp2p/go-libp2p-swarm v0.2.8 h1:cIUUvytBzNQmGSjnXFlI6UpoBGsaud82mJPIJVfkDlg= 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.3.1 h1:UTobu+oQHGdXTOGpZ4RefuVqYoJXcT0EBtSR74m2LkI= +github.com/libp2p/go-libp2p-swarm v0.3.1/go.mod h1:hdv95GWCTmzkgeJpP+GK/9D9puJegb7H57B5hWQR5Kk= 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= @@ -768,8 +768,9 @@ github.com/libp2p/go-libp2p-testing v0.1.0 h1:WaFRj/t3HdMZGNZqnU2pS7pDRBmMeoDx7/ 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-testing v0.2.0 h1:DdC8Dthjf97Hz3t3siZCRD1U3nuNxQgEyTWvLh6ayvw= -github.com/libp2p/go-libp2p-testing v0.2.0/go.mod h1:Qy8sAncLKpwXtS2dSnDOP8ktexIAHKu+J+pnZOFZLTc= +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 h1:ZiBYstPamsi7y6NJZebRudUzsYmVkt998hltyLqf8+g= +github.com/libp2p/go-libp2p-testing v0.3.0/go.mod h1:efZkql4UZ7OVsEfaxNHZPzIehtsBXMrXnCfJIgDti5g= github.com/libp2p/go-libp2p-tls v0.1.3 h1:twKMhMu44jQO+HgQK9X8NHO5HkeJu2QbhLzLJpa8oNM= github.com/libp2p/go-libp2p-tls v0.1.3/go.mod h1:wZfuewxOndz5RTnCAxFliGjvYSDA40sKitV4c50uI1M= github.com/libp2p/go-libp2p-transport v0.0.1/go.mod h1:UzbUs9X+PHOSw7S3ZmeOxfnwaQY5vGDzZmKPod3N3tk= @@ -796,6 +797,8 @@ github.com/libp2p/go-libp2p-yamux v0.2.7 h1:vzKu0NVtxvEIDGCv6mjKRcK0gipSgaXmJZ6j 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 h1:qunEZzWwwmfSBYTtSyd81PlD1TjB5uuWcGYHWVXLbUg= +github.com/libp2p/go-libp2p-yamux v0.4.0/go.mod h1:+DWDjtFMzoAwYLVkNZftoucn7PelNoy5nm3tZ3/Zw30= 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= @@ -810,6 +813,8 @@ github.com/libp2p/go-mplex v0.1.1 h1:huPH/GGRJzmsHR9IZJJsrSwIM5YE2gL4ssgl1YWb/ps 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 h1:Ov/D+8oBlbRkjBs1R1Iua8hJ8cUfbdiW8EOdZuxcgaI= +github.com/libp2p/go-mplex v0.2.0/go.mod h1:0Oy/A9PQlwBytDRp4wSkFnzHYDKcpLot35JQ6msjvYQ= github.com/libp2p/go-msgio v0.0.1/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= 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= @@ -891,6 +896,8 @@ github.com/libp2p/go-yamux v1.3.5 h1:ibuz4naPAully0pN6J/kmUARiqLpnDQIzI/8GCOrljg 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 h1:7nqe0T95T2CWh40IdJ/tp8RMor4ubc9/wYZpB2a/Hx0= +github.com/libp2p/go-yamux v1.4.0/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= github.com/lucas-clemente/quic-go v0.18.1 h1:DMR7guC0NtVS8zNZR3IO7NARZvZygkSC56GGtC6cyys= github.com/lucas-clemente/quic-go v0.18.1/go.mod h1:yXttHsSNxQi8AWijC/vLP+OJczXqzHSOcJrM5ITUlCg= github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= @@ -996,8 +1003,6 @@ github.com/multiformats/go-multiaddr-net v0.2.0 h1:MSXRGN0mFymt6B1yo/6BPnIRpLPEn github.com/multiformats/go-multiaddr-net v0.2.0/go.mod h1:gGdH3UXny6U3cKKYCvpXI5rnK7YaOIEOPVDI9tsJbEA= github.com/multiformats/go-multibase v0.0.1 h1:PN9/v21eLywrFWdFNsFKaU04kLJzuYzmrJR+ubhT9qA= github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= -github.com/multiformats/go-multibase v0.0.2 h1:2pAgScmS1g9XjH7EtAfNhTuyrWYEWcxy0G5Wo85hWDA= -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-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= @@ -1019,8 +1024,8 @@ github.com/multiformats/go-multistream v0.1.0 h1:UpO6jrsjqs46mqAK3n6wKRYFhugss9A 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.1.2 h1:knyamLYMPFPngQjGQ0lhnlys3jtVR/3xV6TREUJr+fE= -github.com/multiformats/go-multistream v0.1.2/go.mod h1:5GZPQZbkWOLOn3J2y4Y99vVW7vOfsAflxARk3x14o6k= +github.com/multiformats/go-multistream v0.2.0 h1:6AuNmQVKUkRnddw2YiDjt5Elit40SFxMJkVnhmETXtU= +github.com/multiformats/go-multistream v0.2.0/go.mod h1:5GZPQZbkWOLOn3J2y4Y99vVW7vOfsAflxARk3x14o6k= github.com/multiformats/go-varint v0.0.1 h1:TR/0rdQtnNxuN2IhiB639xC3tWM4IUi7DkTBVTdGW/M= 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= @@ -1098,6 +1103,7 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR 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/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= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= @@ -1120,6 +1126,7 @@ 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.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= @@ -1132,8 +1139,8 @@ github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUr 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 h1:pa8hGb/2YqsZKovtsgrwcDH1RZhVbTKCjLp47XpqCDs= 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 h1:WN9BUFbdyOsSH/XohnWpXOlq9NBD5sGAB2FciQMUEe8= -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 h1:6b1oIMlUXIpz//VKEDzPVBK8KG7beVwmHIUEBIs/Pns= github.com/smola/gocompat v0.2.0/go.mod h1:1B0MlxbmoZNo3h8guHp8HztB3BSYR5itql9qtVc0ypY= github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= @@ -1170,6 +1177,7 @@ github.com/texttheater/golang-levenshtein v0.0.0-20180516184445-d188e65d659e/go. 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/v2 v2.0.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= 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/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= @@ -1181,8 +1189,8 @@ github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc h1:BCPnHtcboa github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc/go.mod h1:r45hJU7yEoA81k6MWNhpMj/kms0n14dkzkxYHoB96UM= github.com/whyrusleeping/cbor-gen v0.0.0-20200123233031-1cdf64d27158 h1:WXhVOwj2USAXB5oMDwRl3piOux2XMV9TANaYxXHdkoE= 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 h1:wSxKhvbN7kUoP0sfRS+w2tWr45qlU8409i94hHLOT8w= +github.com/whyrusleeping/cbor-gen v0.0.0-20200710004633-5379fc63235d/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-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= @@ -1213,7 +1221,7 @@ github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee/go.mod h1: github.com/whyrusleeping/yamux v1.1.5/go.mod h1:E8LnQQ8HKx5KD29HZFUwM1PxCOdPRzGwur1mcYhXcD8= github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= @@ -1253,6 +1261,8 @@ go.uber.org/zap v1.14.1 h1:nYDKopTbvAPq/NrUVZwT15y2lpROBiLLyoRTbXOYWOo= 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 h1:uFRZXykJGK9lLY4HtgSw44DnIcAM+kRBP7x5m+NpAOM= +go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= 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= @@ -1281,10 +1291,10 @@ golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d h1:1ZiEyfaQIg3Qh0EoqpwAak golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200423211502-4bdfaf469ed5 h1:Q7tZBpemrlsc2I7IyODzhtallWRSm4Q0d09pL6XbQtU= 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-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM= +golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 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= @@ -1316,6 +1326,8 @@ 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.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180524181706-dfa909b99c79/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= @@ -1346,8 +1358,8 @@ golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/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-20200520004742-59133d7f0dd7/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 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1368,6 +1380,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4 golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a h1:WXEvlFVvvGxCJLG6REjsT03iWnKLEWinaScsxF2Vm2o= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 h1:qwRHBd0NqMbJxfbotnDhm2ByMI1Shq4Y6oRJo21SGJA= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 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= @@ -1409,7 +1423,6 @@ golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae h1:/WDfKMnPU+m5M4xB+6x4kaepxRw6jWvR5iDRdvjHgy8= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/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/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 h1:ogLJMz+qpzav7lGMh10LMvAkM/fAoGlaiiHYiFYdm80= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1461,8 +1474,8 @@ golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/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-20200522201501-cb1345f3a375 h1:SjQ2+AKWgZLc1xej6WSzL+Dfs5Uyd5xcZH1mGC411IA= -golang.org/x/tools v0.0.0-20200522201501-cb1345f3a375/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200827010519-17fd2f27a9e3 h1:r3P/5xOq/dK1991B65Oy6E1fRF/2d/fSYZJ/fXGVfJc= +golang.org/x/tools v0.0.0-20200827010519-17fd2f27a9e3/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 h1:/atklqdjdhuosWIl6AIbOeHJjicWYPqR9bpxqxYG2pA= @@ -1504,6 +1517,7 @@ google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvx 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-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= 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= @@ -1511,18 +1525,26 @@ google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZi google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +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 h1:zvIju4sqAGvwKspUQOhwnpcqSbzi7/H6QomNNjTL4sk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.1/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.31.1 h1:SfXqXS5hkufcdZ/mHtYCh53P2b+92WQq/DZcKLgsFRs= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= 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 h1:qdOKuR/EIArgaWNjetjgTzgVTAZ+S/WXVrq9HW9zimw= 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 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= 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.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= 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 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= From 0c4ad11cfb8364bbb10d423ceb6470b6f39870ec Mon Sep 17 00:00:00 2001 From: Chaitanya Date: Mon, 16 Nov 2020 17:52:30 +0530 Subject: [PATCH 040/116] Update files.go --- core/commands/files.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/commands/files.go b/core/commands/files.go index 28ea69634aa..7715c725f1a 100644 --- a/core/commands/files.go +++ b/core/commands/files.go @@ -417,9 +417,9 @@ const ( var filesLsCmd = &cmds.Command{ Helptext: cmds.HelpText{ - Tagline: "List directories in the local mutable namespace. (Both IPFS and MFS paths)", + Tagline: "List directories in the local mutable namespace.", ShortDescription: ` -List directories in the local mutable namespace (Both IPFS and MFS paths). +List directories in the local mutable namespace (Works on both IPFS and MFS paths). Examples: From 475e0ea3993868294b276086a3313a581955bec0 Mon Sep 17 00:00:00 2001 From: Chaitanya Date: Mon, 16 Nov 2020 18:01:22 +0530 Subject: [PATCH 041/116] Update ls.go --- core/commands/ls.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/commands/ls.go b/core/commands/ls.go index e635184b624..4d4c8068a75 100644 --- a/core/commands/ls.go +++ b/core/commands/ls.go @@ -47,9 +47,9 @@ const ( var LsCmd = &cmds.Command{ Helptext: cmds.HelpText{ - Tagline: "List directory contents for Unix filesystem objects. (Only IPFS paths)", + Tagline: "List directory contents for Unix filesystem objects.", ShortDescription: ` -Displays the contents of an IPFS or IPNS object(s) at the given path, with +Displays the contents of an IPFS or IPNS object(s) at the given path, (Won't work with MFS paths - Use 'ipfs files ls' instead) with the following format: From a507a1516278ea87aa60e413fc77d03a13e89774 Mon Sep 17 00:00:00 2001 From: Michael Burns <5170+mburns@users.noreply.github.com> Date: Mon, 16 Nov 2020 18:38:44 +0000 Subject: [PATCH 042/116] Update config.yml --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 4fe87124e89..644ba1846f5 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -294,7 +294,7 @@ jobs: steps: - checkout - setup_remote_docker: - version: "18.09.3" + version: "19.03.13" - run: name: Build Docker image command: | @@ -311,7 +311,7 @@ jobs: steps: - checkout - setup_remote_docker: - version: "18.09.3" + version: "19.03.13" - attach_workspace: at: /tmp/workspace - run: From c2b4a837314491ebd2f80bab2ef278ba010a5457 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Thu, 19 Nov 2020 01:30:51 +0100 Subject: [PATCH 043/116] docs: Add a link in config.md --- docs/config.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/config.md b/docs/config.md index 6119098f8d7..938477b719d 100644 --- a/docs/config.md +++ b/docs/config.md @@ -432,7 +432,7 @@ tool](https://github.com/ipfs/ipfs-ds-convert) to migrate data into the new structures. For more information on possible values for this configuration option, see -docs/datastores.md +[docs/datastores.md](datastores.md) Default: ``` From 59a90b4d497a5114ac9451ea45187b0258efb9e4 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Sat, 14 Nov 2020 08:37:15 +0700 Subject: [PATCH 044/116] update QUIC to quic-go v0.19.2 --- go.mod | 6 +++--- go.sum | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/go.mod b/go.mod index 9e19a7a5077..c64ca1f48bc 100644 --- a/go.mod +++ b/go.mod @@ -73,7 +73,7 @@ require ( github.com/libp2p/go-libp2p-peerstore v0.2.6 github.com/libp2p/go-libp2p-pubsub v0.4.0 github.com/libp2p/go-libp2p-pubsub-router v0.4.0 - github.com/libp2p/go-libp2p-quic-transport v0.9.0 + github.com/libp2p/go-libp2p-quic-transport v0.9.2 github.com/libp2p/go-libp2p-record v0.1.3 github.com/libp2p/go-libp2p-routing-helpers v0.2.3 github.com/libp2p/go-libp2p-secio v0.2.2 @@ -84,7 +84,7 @@ require ( github.com/libp2p/go-socket-activation v0.0.2 github.com/libp2p/go-tcp-transport v0.2.1 github.com/libp2p/go-ws-transport v0.3.1 - github.com/lucas-clemente/quic-go v0.18.1 + github.com/lucas-clemente/quic-go v0.19.2 github.com/mattn/go-runewidth v0.0.9 // indirect github.com/mitchellh/go-homedir v1.1.0 github.com/multiformats/go-multiaddr v0.3.1 @@ -107,4 +107,4 @@ require ( golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 ) -go 1.13 +go 1.14 diff --git a/go.sum b/go.sum index 0597eb9acc6..0d1058e1c2a 100644 --- a/go.sum +++ b/go.sum @@ -727,8 +727,8 @@ github.com/libp2p/go-libp2p-pubsub v0.4.0 h1:YNVRyXqBgv9i4RG88jzoTtkSOaSB45CqHkL github.com/libp2p/go-libp2p-pubsub v0.4.0/go.mod h1:izkeMLvz6Ht8yAISXjx60XUQZMq9ZMe5h2ih4dLIBIQ= 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-quic-transport v0.9.0 h1:WPuq5nV/chmIZIzvrkC2ulSdAQ0P0BDvgvAhZFOZ59E= -github.com/libp2p/go-libp2p-quic-transport v0.9.0/go.mod h1:xyY+IgxL0qsW7Kiutab0+NlxM0/p9yRtrGTYsuMWf70= +github.com/libp2p/go-libp2p-quic-transport v0.9.2 h1:0uKv1AofBFyca4pW9LGDSRwC+oSOuy8jR6Z3YqU/3nU= +github.com/libp2p/go-libp2p-quic-transport v0.9.2/go.mod h1:ZcBDR+oWQV4LyUNfbzHzor0IGYmBCMu7405lEafhCSk= 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= @@ -898,18 +898,18 @@ 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 h1:7nqe0T95T2CWh40IdJ/tp8RMor4ubc9/wYZpB2a/Hx0= github.com/libp2p/go-yamux v1.4.0/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= -github.com/lucas-clemente/quic-go v0.18.1 h1:DMR7guC0NtVS8zNZR3IO7NARZvZygkSC56GGtC6cyys= -github.com/lucas-clemente/quic-go v0.18.1/go.mod h1:yXttHsSNxQi8AWijC/vLP+OJczXqzHSOcJrM5ITUlCg= +github.com/lucas-clemente/quic-go v0.19.2 h1:w8BBYUx5Z+kNpeaOeQW/KzcNsKWhh4O6PeQhb0nURPg= +github.com/lucas-clemente/quic-go v0.19.2/go.mod h1:ZUygOqIoai0ASXXLJ92LTnKdbqh9MHCLTX6Nr1jUrK0= github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 h1:2gxZ0XQIU/5z3Z3bUBu+FXuk2pFbkN6tcwi/pjyaDic= 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/marten-seemann/qpack v0.2.0/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2opoCp2jDKb7wc= +github.com/marten-seemann/qpack v0.2.1/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2opoCp2jDKb7wc= github.com/marten-seemann/qtls v0.10.0 h1:ECsuYUKalRL240rRD4Ri33ISb7kAQ3qGDlrrl55b2pc= github.com/marten-seemann/qtls v0.10.0/go.mod h1:UvMd1oaYDACI99/oZUYLzMCkBXQVT0aGm99sJhbT8hs= -github.com/marten-seemann/qtls-go1-15 v0.1.0 h1:i/YPXVxz8q9umso/5y474CNcHmTpA+5DH+mFPjx6PZg= -github.com/marten-seemann/qtls-go1-15 v0.1.0/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I= +github.com/marten-seemann/qtls-go1-15 v0.1.1 h1:LIH6K34bPVttyXnUWixk0bzH6/N07VxbSabxn5A5gZQ= +github.com/marten-seemann/qtls-go1-15 v0.1.1/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I= 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= From fa81f2a7b34d1476fc6108bedb59afa0a8b6d9b1 Mon Sep 17 00:00:00 2001 From: Chaitanya Date: Tue, 24 Nov 2020 13:42:36 +0530 Subject: [PATCH 045/116] Update core/commands/files.go Co-authored-by: Steven Allen --- core/commands/files.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/commands/files.go b/core/commands/files.go index 7715c725f1a..db498d815ff 100644 --- a/core/commands/files.go +++ b/core/commands/files.go @@ -419,7 +419,7 @@ var filesLsCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "List directories in the local mutable namespace.", ShortDescription: ` -List directories in the local mutable namespace (Works on both IPFS and MFS paths). +List directories in the local mutable namespace (works on both IPFS and MFS paths). Examples: From 1cfd8c756826c5593eee2d9ba8bab190bc49e26b Mon Sep 17 00:00:00 2001 From: Chaitanya Date: Tue, 24 Nov 2020 13:42:48 +0530 Subject: [PATCH 046/116] Update core/commands/unixfs/ls.go Co-authored-by: Steven Allen --- core/commands/unixfs/ls.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/commands/unixfs/ls.go b/core/commands/unixfs/ls.go index 39531bc1a0e..75db0d472b1 100644 --- a/core/commands/unixfs/ls.go +++ b/core/commands/unixfs/ls.go @@ -34,7 +34,7 @@ type LsOutput struct { var LsCmd = &cmds.Command{ 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' instead.", ShortDescription: ` Displays the contents of an IPFS or IPNS object(s) at the given path. From ec64dc5c396e7114590e15909384fabce0035482 Mon Sep 17 00:00:00 2001 From: Chaitanya Date: Tue, 24 Nov 2020 13:51:29 +0530 Subject: [PATCH 047/116] Update ls.go --- core/commands/unixfs/ls.go | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/core/commands/unixfs/ls.go b/core/commands/unixfs/ls.go index 75db0d472b1..ff752d61ed7 100644 --- a/core/commands/unixfs/ls.go +++ b/core/commands/unixfs/ls.go @@ -42,10 +42,7 @@ The JSON output contains size information. For files, the child size is the total size of the file contents. For directories, the child size is the IPFS link size. -This functionality is deprecated, and will be removed in future versions. If -possible, please use 'ipfs ls' instead. - -It is deprecated because 'ipfs file ls' drop some of the ipfs specific info and almost same as 'ipfs ls' +This functionality is deprecated, and will be removed in future versions as it duplicates the functionality of 'ipfs ls'. `, LongDescription: ` Displays the contents of an IPFS or IPNS object(s) at the given path. @@ -64,10 +61,7 @@ Example: > ipfs file ls /ipfs/QmW2WQi7j6c7UgJTarActp7tDNikE4B2qXtFCfLPdsgaTQ cat.jpg -This functionality is deprecated, and will be removed in future versions. If -possible, please use 'ipfs ls' instead. - -It is deprecated because 'ipfs file ls' drop some of the ipfs specific info and almost same as 'ipfs ls' +This functionality is deprecated, and will be removed in future versions as it duplicates the functionality of 'ipfs ls'. `, }, From 8487fad43c1b6abfcfafabe10f9bb6af8cf42a57 Mon Sep 17 00:00:00 2001 From: Chaitanya Date: Tue, 24 Nov 2020 14:00:42 +0530 Subject: [PATCH 048/116] Update ls.go --- core/commands/unixfs/ls.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/commands/unixfs/ls.go b/core/commands/unixfs/ls.go index ff752d61ed7..fee64c713fd 100644 --- a/core/commands/unixfs/ls.go +++ b/core/commands/unixfs/ls.go @@ -43,6 +43,7 @@ is the total size of the file contents. For directories, the child size is the IPFS link size. This functionality is deprecated, and will be removed in future versions as it duplicates the functionality of 'ipfs ls'. +If possible, please use 'ipfs ls' instead. `, LongDescription: ` Displays the contents of an IPFS or IPNS object(s) at the given path. @@ -62,6 +63,7 @@ Example: cat.jpg This functionality is deprecated, and will be removed in future versions as it duplicates the functionality of 'ipfs ls'. +If possible, please use 'ipfs ls' instead. `, }, From f46891e0b574ce2358669de3e11e4122734396e8 Mon Sep 17 00:00:00 2001 From: Chaitanya Date: Tue, 24 Nov 2020 14:02:10 +0530 Subject: [PATCH 049/116] Update ls.go --- core/commands/ls.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/commands/ls.go b/core/commands/ls.go index 4d4c8068a75..4b0114d3341 100644 --- a/core/commands/ls.go +++ b/core/commands/ls.go @@ -49,7 +49,7 @@ var LsCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "List directory contents for Unix filesystem objects.", ShortDescription: ` -Displays the contents of an IPFS or IPNS object(s) at the given path, (Won't work with MFS paths - Use 'ipfs files ls' instead) with +Displays the contents of an IPFS or IPNS object(s) at the given path, with the following format: From 7a50636f9a478ac1a9c14f9d12a8e8c8f7c0e0eb Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 30 Nov 2020 17:47:47 -0800 Subject: [PATCH 050/116] fix: return an error when an unknown object type is passed fixes #7785 --- core/coreapi/object.go | 2 ++ test/sharness/t0051-object.sh | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/core/coreapi/object.go b/core/coreapi/object.go index 413d7954973..4408cec7f64 100644 --- a/core/coreapi/object.go +++ b/core/coreapi/object.go @@ -48,6 +48,8 @@ func (api *ObjectAPI) New(ctx context.Context, opts ...caopts.ObjectNewOption) ( n = new(dag.ProtoNode) case "unixfs-dir": n = ft.EmptyDirNode() + default: + return nil, fmt.Errorf("unknown node type: %s", options.Type) } err = api.dag.Add(ctx, n) diff --git a/test/sharness/t0051-object.sh b/test/sharness/t0051-object.sh index 173148de0c5..95de4fda758 100755 --- a/test/sharness/t0051-object.sh +++ b/test/sharness/t0051-object.sh @@ -223,6 +223,10 @@ test_object_cmd() { ipfs object stat $OUTPUT ' + test_expect_success "'ipfs object new foo' shouldn't crash" ' + test_expect_code 1 ipfs object new foo + ' + test_expect_success "'ipfs object links' gives the correct results" ' echo "$EMPTY_DIR" 4 foo > expected && ipfs object links "$OUTPUT" > actual && From 34e447b0f457c00310f8c7860990d4184ce9191f Mon Sep 17 00:00:00 2001 From: Alex Potsides Date: Tue, 1 Dec 2020 14:17:36 +0000 Subject: [PATCH 051/116] chore: update interop tests and js-ipfs version The internal bin path for js-ipfs changed recently so a major bump to the interop tests was required, this PR updates to the new version. --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 644ba1846f5..fba4a361b03 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -174,8 +174,8 @@ jobs: name: Installing dependencies command: | npm init -y - npm install ipfs@^0.50.1 - npm install ipfs-interop@^3.0.0 + npm install ipfs@^0.52.2 + npm install ipfs-interop@^4.0.0 npm install mocha-circleci-reporter@0.0.3 working_directory: ~/ipfs/go-ipfs/interop - run: From a329e4fc6674909336c56fae2258c6f906af0dbf Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Tue, 1 Dec 2020 11:01:40 -0500 Subject: [PATCH 052/116] p2p-proxy: better request length checking --- core/corehttp/p2p_proxy.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/corehttp/p2p_proxy.go b/core/corehttp/p2p_proxy.go index 0a615c33a2a..c4b34b59241 100644 --- a/core/corehttp/p2p_proxy.go +++ b/core/corehttp/p2p_proxy.go @@ -65,7 +65,7 @@ func parseRequest(request *http.Request) (*proxyRequest, error) { } split = strings.SplitN(path, "/", 7) - if split[3] != "x" || split[5] != "http" { + if len(split) < 7 || split[3] != "x" || split[5] != "http" { return nil, fmt.Errorf("Invalid request path '%s'", path) } From 76f3395ee6c455679d2659a3e1281a98fb3050ec Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Tue, 1 Dec 2020 11:02:48 -0500 Subject: [PATCH 053/116] p2p-proxy: earlier peerID validation check --- core/corehttp/p2p_proxy.go | 5 +++++ test/sharness/t0184-http-proxy-over-p2p.sh | 7 ++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/core/corehttp/p2p_proxy.go b/core/corehttp/p2p_proxy.go index c4b34b59241..1dee5055a50 100644 --- a/core/corehttp/p2p_proxy.go +++ b/core/corehttp/p2p_proxy.go @@ -9,6 +9,7 @@ import ( "strings" core "github.com/ipfs/go-ipfs/core" + peer "github.com/libp2p/go-libp2p-core/peer" protocol "github.com/libp2p/go-libp2p-core/protocol" p2phttp "github.com/libp2p/go-libp2p-http" @@ -60,6 +61,10 @@ func parseRequest(request *http.Request) (*proxyRequest, error) { return nil, fmt.Errorf("Invalid request path '%s'", path) } + if _, err := peer.Decode(split[2]); err != nil { + return nil, fmt.Errorf("Invalid request path '%s'", path) + } + if split[3] == "http" { return &proxyRequest{split[2], protocol.ID("/http"), split[4]}, nil } diff --git a/test/sharness/t0184-http-proxy-over-p2p.sh b/test/sharness/t0184-http-proxy-over-p2p.sh index c1dfcb1d422..9c5308277c2 100755 --- a/test/sharness/t0184-http-proxy-over-p2p.sh +++ b/test/sharness/t0184-http-proxy-over-p2p.sh @@ -194,7 +194,12 @@ test_expect_success 'handle proxy http request invalid request' ' ' test_expect_success 'handle proxy http request unknown proxy peer ' ' - curl_check_response_code 502 p2p/unknown_peer/http/index.txt + UNKNOWN_PEER="k51qzi5uqu5dlmbel1sd8rs4emr3bfosk9bm4eb42514r4lakt4oxw3a3fa2tm" && + curl_check_response_code 502 p2p/$UNKNOWN_PEER/http/index.txt +' + +test_expect_success 'handle proxy http request to invalid proxy peer ' ' + curl_check_response_code 400 p2p/invalid_peer/http/index.txt ' test_expect_success 'handle proxy http request to custom protocol' ' From 9a1f4dd5cc5b88e160383946a51c63c49fb57d20 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Fri, 4 Dec 2020 12:21:09 +0700 Subject: [PATCH 054/116] update QUIC --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index c64ca1f48bc..5d5bb900f76 100644 --- a/go.mod +++ b/go.mod @@ -73,7 +73,7 @@ require ( github.com/libp2p/go-libp2p-peerstore v0.2.6 github.com/libp2p/go-libp2p-pubsub v0.4.0 github.com/libp2p/go-libp2p-pubsub-router v0.4.0 - github.com/libp2p/go-libp2p-quic-transport v0.9.2 + github.com/libp2p/go-libp2p-quic-transport v0.9.3 github.com/libp2p/go-libp2p-record v0.1.3 github.com/libp2p/go-libp2p-routing-helpers v0.2.3 github.com/libp2p/go-libp2p-secio v0.2.2 @@ -84,7 +84,7 @@ require ( github.com/libp2p/go-socket-activation v0.0.2 github.com/libp2p/go-tcp-transport v0.2.1 github.com/libp2p/go-ws-transport v0.3.1 - github.com/lucas-clemente/quic-go v0.19.2 + github.com/lucas-clemente/quic-go v0.19.3 github.com/mattn/go-runewidth v0.0.9 // indirect github.com/mitchellh/go-homedir v1.1.0 github.com/multiformats/go-multiaddr v0.3.1 diff --git a/go.sum b/go.sum index 0d1058e1c2a..aefb59800d3 100644 --- a/go.sum +++ b/go.sum @@ -727,8 +727,8 @@ github.com/libp2p/go-libp2p-pubsub v0.4.0 h1:YNVRyXqBgv9i4RG88jzoTtkSOaSB45CqHkL github.com/libp2p/go-libp2p-pubsub v0.4.0/go.mod h1:izkeMLvz6Ht8yAISXjx60XUQZMq9ZMe5h2ih4dLIBIQ= 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-quic-transport v0.9.2 h1:0uKv1AofBFyca4pW9LGDSRwC+oSOuy8jR6Z3YqU/3nU= -github.com/libp2p/go-libp2p-quic-transport v0.9.2/go.mod h1:ZcBDR+oWQV4LyUNfbzHzor0IGYmBCMu7405lEafhCSk= +github.com/libp2p/go-libp2p-quic-transport v0.9.3 h1:e6eLN55agvemeYzdJTzIylVbLD5PJr0RJANr9HM+FVc= +github.com/libp2p/go-libp2p-quic-transport v0.9.3/go.mod h1:STiznVmrLMFPXCrkEbNna/VxgdxBatcK0SA+1FSdxnI= 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= @@ -898,8 +898,8 @@ 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 h1:7nqe0T95T2CWh40IdJ/tp8RMor4ubc9/wYZpB2a/Hx0= github.com/libp2p/go-yamux v1.4.0/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= -github.com/lucas-clemente/quic-go v0.19.2 h1:w8BBYUx5Z+kNpeaOeQW/KzcNsKWhh4O6PeQhb0nURPg= -github.com/lucas-clemente/quic-go v0.19.2/go.mod h1:ZUygOqIoai0ASXXLJ92LTnKdbqh9MHCLTX6Nr1jUrK0= +github.com/lucas-clemente/quic-go v0.19.3 h1:eCDQqvGBB+kCTkA0XrAFtNe81FMa0/fn4QSoeAbmiF4= +github.com/lucas-clemente/quic-go v0.19.3/go.mod h1:ADXpNbTQjq1hIzCpB+y/k5iz4n4z4IwqoLb94Kh5Hu8= github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 h1:2gxZ0XQIU/5z3Z3bUBu+FXuk2pFbkN6tcwi/pjyaDic= From 0b1276db596e9d1cfdf1bc584f8ee3344a76910d Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Fri, 4 Dec 2020 15:28:54 -0500 Subject: [PATCH 055/116] Use datastore based pinner --- core/node/core.go | 16 +++++++--------- go.mod | 2 +- go.sum | 4 ++-- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/core/node/core.go b/core/node/core.go index 4c522dbcfc3..cb757d81968 100644 --- a/core/node/core.go +++ b/core/node/core.go @@ -3,6 +3,7 @@ package node import ( "context" "fmt" + "time" "github.com/ipfs/go-bitswap" "github.com/ipfs/go-bitswap/network" @@ -12,8 +13,8 @@ import ( "github.com/ipfs/go-filestore" "github.com/ipfs/go-ipfs-blockstore" "github.com/ipfs/go-ipfs-exchange-interface" - "github.com/ipfs/go-ipfs-exchange-offline" "github.com/ipfs/go-ipfs-pinner" + "github.com/ipfs/go-ipfs-pinner/dspinner" "github.com/ipfs/go-ipld-format" "github.com/ipfs/go-merkledag" "github.com/ipfs/go-mfs" @@ -41,7 +42,6 @@ func BlockService(lc fx.Lifecycle, bs blockstore.Blockstore, rem exchange.Interf // Pinning creates new pinner which tells GC which blocks should be kept func Pinning(bstore blockstore.Blockstore, ds format.DAGService, repo repo.Repo) (pin.Pinner, error) { - internalDag := merkledag.NewDAGService(blockservice.New(bstore, offline.Exchange(bstore))) rootDS := repo.Datastore() syncFn := func() error { @@ -51,15 +51,13 @@ func Pinning(bstore blockstore.Blockstore, ds format.DAGService, repo repo.Repo) return rootDS.Sync(filestore.FilestorePrefix) } syncDs := &syncDagService{ds, syncFn} - syncInternalDag := &syncDagService{internalDag, syncFn} - pinning, err := pin.LoadPinner(rootDS, syncDs, syncInternalDag) + ctx, cancel := context.WithTimeout(context.TODO(), 2*time.Minute) + defer cancel() + + pinning, err := dspinner.New(ctx, rootDS, syncDs) if err != nil { - // TODO: we should move towards only running 'NewPinner' explicitly on - // node init instead of implicitly here as a result of the pinner keys - // not being found in the datastore. - // this is kinda sketchy and could cause data loss - pinning = pin.NewPinner(rootDS, syncDs, syncInternalDag) + return nil, err } return pinning, nil diff --git a/go.mod b/go.mod index 5d5bb900f76..8c43c8c87d4 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( github.com/ipfs/go-ipfs-exchange-interface v0.0.1 github.com/ipfs/go-ipfs-exchange-offline v0.0.1 github.com/ipfs/go-ipfs-files v0.0.8 - github.com/ipfs/go-ipfs-pinner v0.0.4 + github.com/ipfs/go-ipfs-pinner v0.1.0 github.com/ipfs/go-ipfs-posinfo v0.0.1 github.com/ipfs/go-ipfs-provider v0.4.3 github.com/ipfs/go-ipfs-routing v0.1.0 diff --git a/go.sum b/go.sum index aefb59800d3..f49ce66adf9 100644 --- a/go.sum +++ b/go.sum @@ -388,8 +388,8 @@ github.com/ipfs/go-ipfs-files v0.0.3/go.mod h1:INEFm0LL2LWXBhNJ2PMIIb2w45hpXgPjN 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= github.com/ipfs/go-ipfs-flags v0.0.1/go.mod h1:RnXBb9WV53GSfTrSDVK61NLTFKvWc60n+K9EgCDh+rA= -github.com/ipfs/go-ipfs-pinner v0.0.4 h1:EmxhS3vDsCK/rZrsgxX0Le9m2drBcGlUd7ah/VyFYVE= -github.com/ipfs/go-ipfs-pinner v0.0.4/go.mod h1:s4kFZWLWGDudN8Jyd/GTpt222A12C2snA2+OTdy/7p8= +github.com/ipfs/go-ipfs-pinner v0.1.0 h1:rjSrbUDYd1YYHZ5dOgu+QEOuLcU0m/2a/brcxC/ReeU= +github.com/ipfs/go-ipfs-pinner v0.1.0/go.mod h1:EzyyaWCWeZJ/he9cDBH6QrEkSuRqTRWMmCoyNkylTTg= 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= From 9bc8f6d5b514cb599cbb1999ca22c933f7d77d50 Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Fri, 4 Dec 2020 15:30:04 -0500 Subject: [PATCH 056/116] bump repo version to 11 --- repo/fsrepo/fsrepo.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repo/fsrepo/fsrepo.go b/repo/fsrepo/fsrepo.go index 6cd312e40aa..011c47a1d7c 100644 --- a/repo/fsrepo/fsrepo.go +++ b/repo/fsrepo/fsrepo.go @@ -35,7 +35,7 @@ const LockFile = "repo.lock" var log = logging.Logger("fsrepo") // version number that we are currently expecting to see -var RepoVersion = 10 +var RepoVersion = 11 var migrationInstructions = `See https://github.com/ipfs/fs-repo-migrations/blob/master/run.md Sorry for the inconvenience. In the future, these will run automatically.` From 08e058427f760d8d171a6666d955ca7146cd352a Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Mon, 7 Dec 2020 17:06:29 -0500 Subject: [PATCH 057/116] Update GitHub documentation issue template Uses the correct URL for the documentation repo --- .github/ISSUE_TEMPLATE/doc.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/doc.md b/.github/ISSUE_TEMPLATE/doc.md index 552a2951f55..0a5432f5708 100644 --- a/.github/ISSUE_TEMPLATE/doc.md +++ b/.github/ISSUE_TEMPLATE/doc.md @@ -3,7 +3,7 @@ name: 'Documentation Issue' about: 'Report missing, erroneous docs, broken links or propose new go-ipfs docs' labels: topic/docs-ipfs, need/triage --- - + #### Location From 474f1cda9a4e2055541edcba558962697f9ed850 Mon Sep 17 00:00:00 2001 From: Zaurbek Zhakupov Date: Tue, 8 Dec 2020 01:26:33 -0500 Subject: [PATCH 058/116] Fixed typos in remove.go comments --- blocks/blockstoreutil/remove.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/blocks/blockstoreutil/remove.go b/blocks/blockstoreutil/remove.go index 52a18fd0f3a..ae645f6fd30 100644 --- a/blocks/blockstoreutil/remove.go +++ b/blocks/blockstoreutil/remove.go @@ -12,10 +12,10 @@ import ( ) // RemovedBlock is used to represent the result of removing a block. -// If a block was removed successfully than the Error string will be -// empty. If a block could not be removed than Error will contain the +// 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 // 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 +// 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"` From 8a05c59d3dc6205e72c9c59b40cda0d10efa4a64 Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Tue, 8 Dec 2020 14:46:00 -0500 Subject: [PATCH 059/116] chore: update dist path --- repo/fsrepo/migrations/migrations.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repo/fsrepo/migrations/migrations.go b/repo/fsrepo/migrations/migrations.go index 186d4a10dc0..ad94b04a652 100644 --- a/repo/fsrepo/migrations/migrations.go +++ b/repo/fsrepo/migrations/migrations.go @@ -15,7 +15,7 @@ import ( "strings" ) -var DistPath = "https://ipfs.io/ipfs/Qmdo5m6bpQXCayzfGghyvgXJdVHSsXsCKDUo9vWktDKq3K" +var DistPath = "https://ipfs.io/ipfs/QmahS3i7MkjVVDjPs6CoPhCKGi27LkHGXrzQ45jCRX6wcK" func init() { if dist := os.Getenv("IPFS_DIST_PATH"); dist != "" { From 79d96815a8d396b46acefa25d35b7c5997de6853 Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Tue, 8 Dec 2020 16:57:01 -0500 Subject: [PATCH 060/116] chore: update deps --- go.mod | 14 +++++++------- go.sum | 24 ++++++++++++++---------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/go.mod b/go.mod index 8c43c8c87d4..3419cb7d47e 100644 --- a/go.mod +++ b/go.mod @@ -9,25 +9,25 @@ require ( github.com/dustin/go-humanize v1.0.0 github.com/elgris/jsondiff v0.0.0-20160530203242-765b5c24c302 github.com/fsnotify/fsnotify v1.4.9 - github.com/gabriel-vasile/mimetype v1.1.1 + github.com/gabriel-vasile/mimetype v1.1.2 github.com/go-bindata/go-bindata/v3 v3.1.3 github.com/gogo/protobuf v1.3.1 github.com/hashicorp/go-multierror v1.1.0 github.com/hashicorp/golang-lru v0.5.4 - github.com/ipfs/go-bitswap v0.3.2 + github.com/ipfs/go-bitswap v0.3.3 github.com/ipfs/go-block-format v0.0.2 github.com/ipfs/go-blockservice v0.1.4 github.com/ipfs/go-cid v0.0.7 github.com/ipfs/go-cidutil v0.0.2 github.com/ipfs/go-datastore v0.4.5 github.com/ipfs/go-detect-race v0.0.1 - github.com/ipfs/go-ds-badger v0.2.5 + github.com/ipfs/go-ds-badger v0.2.6 github.com/ipfs/go-ds-flatfs v0.4.5 github.com/ipfs/go-ds-leveldb v0.4.2 github.com/ipfs/go-ds-measure v0.1.0 github.com/ipfs/go-filestore v0.0.3 github.com/ipfs/go-fs-lock v0.0.6 - github.com/ipfs/go-graphsync v0.5.0 + github.com/ipfs/go-graphsync v0.5.1 github.com/ipfs/go-ipfs-blockstore v0.1.4 github.com/ipfs/go-ipfs-chunker v0.0.5 github.com/ipfs/go-ipfs-cmds v0.4.0 @@ -41,7 +41,7 @@ require ( github.com/ipfs/go-ipfs-provider v0.4.3 github.com/ipfs/go-ipfs-routing v0.1.0 github.com/ipfs/go-ipfs-util v0.0.2 - github.com/ipfs/go-ipld-cbor v0.0.4 + github.com/ipfs/go-ipld-cbor v0.0.5 github.com/ipfs/go-ipld-format v0.2.0 github.com/ipfs/go-ipld-git v0.0.3 github.com/ipfs/go-ipns v0.0.2 @@ -69,7 +69,7 @@ require ( 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.3.0 - github.com/libp2p/go-libp2p-noise v0.1.1 + github.com/libp2p/go-libp2p-noise v0.1.2 github.com/libp2p/go-libp2p-peerstore v0.2.6 github.com/libp2p/go-libp2p-pubsub v0.4.0 github.com/libp2p/go-libp2p-pubsub-router v0.4.0 @@ -99,7 +99,7 @@ require ( github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc github.com/whyrusleeping/go-sysinfo v0.0.0-20190219211824-4a357d4b90b1 github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 - github.com/whyrusleeping/tar-utils v0.0.0-20180509141711-8c6c8ba81d5c + github.com/whyrusleeping/tar-utils v0.0.0-20201201191210-20a61371de5b go.uber.org/fx v1.13.1 go.uber.org/zap v1.16.0 golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a diff --git a/go.sum b/go.sum index f49ce66adf9..a425b5e0bd4 100644 --- a/go.sum +++ b/go.sum @@ -152,8 +152,8 @@ github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV 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.1 h1:qbN9MPuRf3bstHu9zkI9jDWNfH//9+9kHxr9oRBBBOA= -github.com/gabriel-vasile/mimetype v1.1.1/go.mod h1:6CDPel/o/3/s4+bp6kIbsWATq8pmgOisOPG40CJa6To= +github.com/gabriel-vasile/mimetype v1.1.2 h1:gaPnPcNor5aZSVCJVSGipcpbgMWiAAj9z182ocSGbHU= +github.com/gabriel-vasile/mimetype v1.1.2/go.mod h1:6CDPel/o/3/s4+bp6kIbsWATq8pmgOisOPG40CJa6To= 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= @@ -283,8 +283,8 @@ 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.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.2 h1:TdKx7lpidYe2dMAKfdeNS26y6Pc/AZX/i8doI1GV210= -github.com/ipfs/go-bitswap v0.3.2/go.mod h1:AyWWfN3moBzQX0banEtfKOfbXb3ZeoOeXnZGNPV9S6w= +github.com/ipfs/go-bitswap v0.3.3 h1:CrTO3OiOYFBcdliw074/C7T2QYHEOsPClgvR6RIYcO4= +github.com/ipfs/go-bitswap v0.3.3/go.mod h1:AyWWfN3moBzQX0banEtfKOfbXb3ZeoOeXnZGNPV9S6w= 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= @@ -338,8 +338,8 @@ github.com/ipfs/go-ds-badger v0.2.1 h1:RsC9DDlwFhFdfT+s2PeC8joxbSp2YMufK8w/RBOxK github.com/ipfs/go-ds-badger v0.2.1/go.mod h1:Tx7l3aTph3FMFrRS838dcSJh+jjA7cX9DrGVwx/NOwE= github.com/ipfs/go-ds-badger v0.2.3 h1:J27YvAcpuA5IvZUbeBxOcQgqnYHUPxoygc6QxxkodZ4= github.com/ipfs/go-ds-badger v0.2.3/go.mod h1:pEYw0rgg3FIrywKKnL+Snr+w/LjJZVMTBRn4FS6UHUk= -github.com/ipfs/go-ds-badger v0.2.5 h1:oKRP6xVdgunjioOvaW4Ue2N7rBI7h/sWNERHTguUmpE= -github.com/ipfs/go-ds-badger v0.2.5/go.mod h1:02rnztVKA4aZwDuaRPTf8mpqcKmXP7mLl6JPxd14JHA= +github.com/ipfs/go-ds-badger v0.2.6 h1:Hy8jw4rifxtRDrqpvC1yh36oIyE37KDzsUzlHUPOFiU= +github.com/ipfs/go-ds-badger v0.2.6/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-leveldb v0.0.1/go.mod h1:feO8V3kubwsEF22n0YRQCffeb79OOYIykR4L04tMOYc= @@ -355,8 +355,8 @@ github.com/ipfs/go-filestore v0.0.3 h1:MhZ1jT5K3NewZwim6rS/akcJLm1xM+r6nz6foeB9E github.com/ipfs/go-filestore v0.0.3/go.mod h1:dvXRykFzyyXN2CdNlRGzDAkXMDPyI+D7JE066SiKLSE= github.com/ipfs/go-fs-lock v0.0.6 h1:sn3TWwNVQqSeNjlWy6zQ1uUGAZrV3hPOyEA6y1/N2a0= github.com/ipfs/go-fs-lock v0.0.6/go.mod h1:OTR+Rj9sHiRubJh3dRhD15Juhd/+w6VPOY28L7zESmM= -github.com/ipfs/go-graphsync v0.5.0 h1:iaByvxq88Ys1KcaQzTS1wmRhNsNEo3SaUiSGqTSbGmM= -github.com/ipfs/go-graphsync v0.5.0/go.mod h1:e2ZxnClqBBYAtd901g9vXMJzS47labjAtOzsWtOzKNk= +github.com/ipfs/go-graphsync v0.5.1 h1:4fXBRvRKicTgTmCFMmEua/H5jvmAOLgU9Z7PCPWt2ec= +github.com/ipfs/go-graphsync v0.5.1/go.mod h1:e2ZxnClqBBYAtd901g9vXMJzS47labjAtOzsWtOzKNk= github.com/ipfs/go-ipfs-blockstore v0.0.1/go.mod h1:d3WClOmRQKFnJ0Jz/jj/zmksX0ma1gROTlovZKBmN08= github.com/ipfs/go-ipfs-blockstore v0.1.0 h1:V1GZorHFUIB6YgTJQdq7mcaIpUfCM3fCyVi+MTo9O88= github.com/ipfs/go-ipfs-blockstore v0.1.0/go.mod h1:5aD0AvHPi7mZc6Ci1WCAhiBQu2IsfTduLl+422H6Rqw= @@ -410,6 +410,8 @@ github.com/ipfs/go-ipld-cbor v0.0.3 h1:ENsxvybwkmke7Z/QJOmeJfoguj6GH3Y0YOaGrfy9Q 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 h1:OVAGlyYT6JPZ0pEfGntFPS40lfrDmaDbQwNHEY2G9Zs= github.com/ipfs/go-ipld-format v0.0.2/go.mod h1:4B6+FM2u9OJ9zCV+kSbgFAZlOrv1Hqbf0INGQgiKf9k= @@ -700,6 +702,8 @@ 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 h1:vqYQWvnIcHpIoWJKC7Al4D6Hgj0H012TuXRhPwSMGpQ= github.com/libp2p/go-libp2p-noise v0.1.1/go.mod h1:QDFLdKX7nluB7DEnlVPbz7xlLHdwHFA9HiohJRr3vwM= +github.com/libp2p/go-libp2p-noise v0.1.2 h1:IH9GRihQJTx56obm+GnpdPX4KeVIlvpXrP6xnJ0wxWk= +github.com/libp2p/go-libp2p-noise v0.1.2/go.mod h1:9B10b7ueo7TIxZHHcjcDCo5Hd6kfKT2m77by82SFRfE= 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 h1:EQ8kMjaCUwt/Y5uLgjT8iY2qg0mGUT0N1zUjer50DsY= @@ -1214,8 +1218,8 @@ github.com/whyrusleeping/mdns v0.0.0-20190826153040-b9b60ed33aa9 h1:Y1/FEOpaCpD2 github.com/whyrusleeping/mdns v0.0.0-20190826153040-b9b60ed33aa9/go.mod h1:j4l84WPFclQPj320J9gp0XwNKBb3U0zt5CBqjPp22G4= github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 h1:E9S12nwJwEOXe2d6gT6qxdvqMnNq+VnSsKPgm2ZZNds= github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= -github.com/whyrusleeping/tar-utils v0.0.0-20180509141711-8c6c8ba81d5c h1:GGsyl0dZ2jJgVT+VvWBf/cNijrHRhkrTjkmp5wg7li0= -github.com/whyrusleeping/tar-utils v0.0.0-20180509141711-8c6c8ba81d5c/go.mod h1:xxcJeBb7SIUl/Wzkz1eVKJE/CB34YNrqX2TQI6jY9zs= +github.com/whyrusleeping/tar-utils v0.0.0-20201201191210-20a61371de5b h1:wA3QeTsaAXybLL2kb2cKhCAQTHgYTMwuI8lBlJSv5V8= +github.com/whyrusleeping/tar-utils v0.0.0-20201201191210-20a61371de5b/go.mod h1:xT1Y5p2JR2PfSZihE0s4mjdJaRGp1waCTf5JzhQLBck= 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/whyrusleeping/yamux v1.1.5/go.mod h1:E8LnQQ8HKx5KD29HZFUwM1PxCOdPRzGwur1mcYhXcD8= From 3d9821260adabb6b8a573fc5cdd7a4619f663d50 Mon Sep 17 00:00:00 2001 From: lanzafame Date: Fri, 24 Jul 2020 12:59:26 +1000 Subject: [PATCH 061/116] register quic opencensus metrics --- cmd/ipfs/daemon.go | 1 + core/corehttp/metrics.go | 47 ++++++++++++++++++++++++++++++++++++---- go.mod | 2 ++ go.sum | 19 ++++++++++++++++ plugin/loader/preload.sh | 4 +++- 5 files changed, 68 insertions(+), 5 deletions(-) diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/daemon.go index 4fd0a16f71a..b3cb9f7b523 100644 --- a/cmd/ipfs/daemon.go +++ b/cmd/ipfs/daemon.go @@ -528,6 +528,7 @@ func serveHTTPApi(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, error var opts = []corehttp.ServeOption{ corehttp.MetricsCollectionOption("api"), + corehttp.MetricsOpenCensusCollectionOption(), corehttp.CheckVersionOption(), corehttp.CommandsOption(*cctx), corehttp.WebUIOption, diff --git a/core/corehttp/metrics.go b/core/corehttp/metrics.go index 1288484d3ff..e5bd81283b9 100644 --- a/core/corehttp/metrics.go +++ b/core/corehttp/metrics.go @@ -3,9 +3,14 @@ package corehttp import ( "net" "net/http" + "time" core "github.com/ipfs/go-ipfs/core" + "go.opencensus.io/stats/view" + "go.opencensus.io/zpages" + ocprom "contrib.go.opencensus.io/exporter/prometheus" + quicmetrics "github.com/lucas-clemente/quic-go/metrics" prometheus "github.com/prometheus/client_golang/prometheus" promhttp "github.com/prometheus/client_golang/prometheus/promhttp" ) @@ -18,9 +23,43 @@ func MetricsScrapingOption(path string) ServeOption { } } +// This adds collection of OpenCensus metrics +func MetricsOpenCensusCollectionOption() ServeOption { + return func(_ *core.IpfsNode, _ net.Listener, mux *http.ServeMux) (*http.ServeMux, error) { + log.Error("Init OpenCensus") + + promRegistry := prometheus.NewRegistry() + pe, err := ocprom.NewExporter(ocprom.Options{ + Namespace: "ipfs_oc", + Registry: promRegistry, + OnError: func(err error) { + log.Errorw("OC ERROR", "error", err) + }, + }) + if err != nil { + return nil, err + } + + // register prometheus with opencensus + view.RegisterExporter(pe) + view.SetReportingPeriod(2 * time.Second) + + if err := view.Register(quicmetrics.DefaultViews...); err != nil { + return nil, err + } + + // Construct the mux + zpages.Handle(mux, "/ocmetrics/debug") + mux.Handle("/ocmetrics", pe) + + return mux, nil + } +} + // This adds collection of net/http-related metrics func MetricsCollectionOption(handlerName string) ServeOption { return func(_ *core.IpfsNode, _ net.Listener, mux *http.ServeMux) (*http.ServeMux, error) { + promRegistry := prometheus.NewRegistry() // Adapted from github.com/prometheus/client_golang/prometheus/http.go // Work around https://github.com/prometheus/client_golang/pull/311 opts := prometheus.SummaryOpts{ @@ -40,7 +79,7 @@ func MetricsCollectionOption(handlerName string) ServeOption { }, []string{"method", "code"}, ) - if err := prometheus.Register(reqCnt); err != nil { + if err := promRegistry.Register(reqCnt); err != nil { if are, ok := err.(prometheus.AlreadyRegisteredError); ok { reqCnt = are.ExistingCollector.(*prometheus.CounterVec) } else { @@ -51,7 +90,7 @@ func MetricsCollectionOption(handlerName string) ServeOption { opts.Name = "request_duration_seconds" opts.Help = "The HTTP request latencies in seconds." reqDur := prometheus.NewSummaryVec(opts, nil) - if err := prometheus.Register(reqDur); err != nil { + if err := promRegistry.Register(reqDur); err != nil { if are, ok := err.(prometheus.AlreadyRegisteredError); ok { reqDur = are.ExistingCollector.(*prometheus.SummaryVec) } else { @@ -62,7 +101,7 @@ func MetricsCollectionOption(handlerName string) ServeOption { opts.Name = "request_size_bytes" opts.Help = "The HTTP request sizes in bytes." reqSz := prometheus.NewSummaryVec(opts, nil) - if err := prometheus.Register(reqSz); err != nil { + if err := promRegistry.Register(reqSz); err != nil { if are, ok := err.(prometheus.AlreadyRegisteredError); ok { reqSz = are.ExistingCollector.(*prometheus.SummaryVec) } else { @@ -73,7 +112,7 @@ func MetricsCollectionOption(handlerName string) ServeOption { opts.Name = "response_size_bytes" opts.Help = "The HTTP response sizes in bytes." resSz := prometheus.NewSummaryVec(opts, nil) - if err := prometheus.Register(resSz); err != nil { + if err := promRegistry.Register(resSz); err != nil { if are, ok := err.(prometheus.AlreadyRegisteredError); ok { resSz = are.ExistingCollector.(*prometheus.SummaryVec) } else { diff --git a/go.mod b/go.mod index 3419cb7d47e..dc4979e7d31 100644 --- a/go.mod +++ b/go.mod @@ -2,6 +2,7 @@ module github.com/ipfs/go-ipfs require ( bazil.org/fuse v0.0.0-20200117225306-7b5117fecadc + contrib.go.opencensus.io/exporter/prometheus v0.2.0 github.com/blang/semver v3.5.1+incompatible github.com/bren2010/proquint v0.0.0-20160323162903-38337c27106d github.com/cheggaaa/pb v1.0.29 @@ -100,6 +101,7 @@ require ( github.com/whyrusleeping/go-sysinfo v0.0.0-20190219211824-4a357d4b90b1 github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 github.com/whyrusleeping/tar-utils v0.0.0-20201201191210-20a61371de5b + go.opencensus.io v0.22.4 go.uber.org/fx v1.13.1 go.uber.org/zap v1.16.0 golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a diff --git a/go.sum b/go.sum index a425b5e0bd4..164d685a548 100644 --- a/go.sum +++ b/go.sum @@ -18,6 +18,8 @@ cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2k cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= 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= +contrib.go.opencensus.io/exporter/prometheus v0.2.0 h1:9PUk0/8V0LGoPqVCrf8fQZJkFGBxudu8jOjQSMwoD6w= +contrib.go.opencensus.io/exporter/prometheus v0.2.0/go.mod h1:TYmVAyE8Tn1lyPcltF5IYYfWp2KHu7lQGIZnj8iZMys= 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= @@ -40,8 +42,10 @@ github.com/Stebalien/go-bitfield v0.0.1 h1:X3kbSSPUaJK60wV2hjOPZwmpljr6VGCqdq4cB github.com/Stebalien/go-bitfield v0.0.1/go.mod h1:GNjFpasyUVkHMsfEOk8EFLJ9syQ6SI+XWrX9Wf2XH0s= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= 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 h1:Hs82Z41s6SdL1CELW+XaDYmOH4hkBN4/N9og/AsOv7E= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= 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= @@ -81,6 +85,7 @@ github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QH github.com/census-instrumentation/opencensus-proto v0.2.1/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.0/go.mod h1:dgIUBU3pDso/gPgZ1osOZ0iQf77oPR28Tjxl5dIMyVM= 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/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE= @@ -514,6 +519,7 @@ github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= 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.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= 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= @@ -527,6 +533,7 @@ github.com/kisielk/errcheck v1.2.0 h1:reN85Pxc5larApoH1keMBiu2GWtPqXQ1nc9gx+jOU+ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= 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/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b h1:wxtKgYHEncAU00muMD06dzLiahtGM1eouRNOzVV7tdQ= github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= @@ -1084,6 +1091,7 @@ github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.2.1/go.mod h1:XMU6Z2MjaRKVu/dC1qupJI9SiNkDYzz3xecMgSW/F+U= github.com/prometheus/client_golang v1.7.1 h1:NTGy1Ja9pByO+xAeH/qiWnLrKtr3hJPNjaVUwnjpdpA= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= @@ -1095,14 +1103,19 @@ github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6T github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= 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.10.0 h1:RyRA7RzGXQZiW+tGMr7sxa85G1z0yOpM1qq5c8lNawc= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= 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.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= +github.com/prometheus/procfs v0.0.6/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3 h1:F0+tqvhOksq22sc6iCHF5WGlWjdwj92p0udFh1VFBS8= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/statsd_exporter v0.15.0 h1:UiwC1L5HkxEPeapXdm2Ye0u1vUJfTj7uwT5yydYpa1E= +github.com/prometheus/statsd_exporter v0.15.0/go.mod h1:Dv8HnkoLQkeEjkIE4/2ndAA7WL1zHKK7WMqFQqu72rw= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= @@ -1134,6 +1147,7 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV 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.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/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v1.0.0 h1:UVQPSSmc3qtTi+zPPkCXvZX9VvW/xT/NsRvKfwY81a8= @@ -1415,7 +1429,9 @@ golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191113165036-4c7a9d0fe056/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-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1520,7 +1536,9 @@ google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvx 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-20200212174721-66ed5ce911ce h1:1mbrb1tUU+Zmt5C94IGKADBTJZjZXAd+BubWi7r9EiI= google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= @@ -1549,6 +1567,7 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= 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 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= diff --git a/plugin/loader/preload.sh b/plugin/loader/preload.sh index 30ba8b73e4b..256a23bc9f2 100755 --- a/plugin/loader/preload.sh +++ b/plugin/loader/preload.sh @@ -2,8 +2,10 @@ DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +LIST="$DIR/preload_list" + to_preload() { - awk 'NF' "$DIR/preload_list" | sed '/^#/d' + awk 'NF' $LIST | sed '/^#/d' if [[ -n "$IPFS_PLUGINS" ]]; then for plugin in $IPFS_PLUGINS; do echo "$plugin github.com/ipfs/go-ipfs/plugin/plugins/$plugin *" From 024bf80e6a574e791b397bcba5875dae76c32c3b Mon Sep 17 00:00:00 2001 From: lanzafame Date: Tue, 29 Sep 2020 10:35:07 +1000 Subject: [PATCH 062/116] change the scraping url --- core/corehttp/metrics.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/corehttp/metrics.go b/core/corehttp/metrics.go index e5bd81283b9..de0dcd7438f 100644 --- a/core/corehttp/metrics.go +++ b/core/corehttp/metrics.go @@ -49,8 +49,8 @@ func MetricsOpenCensusCollectionOption() ServeOption { } // Construct the mux - zpages.Handle(mux, "/ocmetrics/debug") - mux.Handle("/ocmetrics", pe) + zpages.Handle(mux, "/debug/metrics/oc/debugz") + mux.Handle("/debug/metrics/oc", pe) return mux, nil } From a8c7980721909f9cd16c35d699bc481574512c38 Mon Sep 17 00:00:00 2001 From: Petar Maymounkov Date: Tue, 8 Dec 2020 17:32:33 -0800 Subject: [PATCH 063/116] add remote pinning to ipfs command (#7661) Added support for remote pinning services A pinning service is a service that accepts CIDs from a user in order to host the data associated with them. The spec for these services is defined at https://github.com/ipfs/pinning-services-api-spec Support is available via the `ipfs pin remote` CLI and the corresponding HTTP API Co-authored-by: Petar Maymounkov Co-authored-by: Marcin Rataj Co-authored-by: Adin Schmahmann --- .circleci/config.yml | 32 +- core/commands/commands_test.go | 10 +- core/commands/config.go | 80 +++- core/commands/{ => pin}/pin.go | 3 +- core/commands/pin/remotepin.go | 671 +++++++++++++++++++++++++++++++ core/commands/root.go | 3 +- docs/config.md | 54 +++ go.mod | 6 +- go.sum | 51 +-- test/sharness/t0700-remotepin.sh | 271 +++++++++++++ 10 files changed, 1127 insertions(+), 54 deletions(-) rename core/commands/{ => pin}/pin.go (99%) create mode 100644 core/commands/pin/remotepin.go create mode 100755 test/sharness/t0700-remotepin.sh diff --git a/.circleci/config.yml b/.circleci/config.yml index 644ba1846f5..d0d0c9114e6 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -118,14 +118,42 @@ jobs: - store_artifacts: path: /tmp/circleci-test-results sharness: - executor: golang + machine: + image: ubuntu-2004:202010-01 + working_directory: ~/ipfs/go-ipfs + environment: + <<: *default_environment + GO111MODULE: "on" + TEST_NO_DOCKER: 1 + TEST_NO_FUSE: 1 + GOPATH: /home/circleci/go + TEST_VERBOSE: 1 steps: - run: sudo apt install socat - checkout + + - run: + mkdir rb-pinning-service-api && + cd rb-pinning-service-api && + git init && + git remote add origin https://github.com/ipfs-shipyard/rb-pinning-service-api.git && + git fetch --depth 1 origin 773c3adbb421c551d2d89288abac3e01e1f7c3a8 && + git checkout FETCH_HEAD + - run: + cd rb-pinning-service-api && + docker-compose pull && + docker-compose up -d + - *make_out_dirs - *restore_gomod - - run: make -O -j 10 coverage/sharness_tests.coverprofile test/sharness/test-results/sharness.xml TEST_GENERATE_JUNIT=1 CONTINUE_ON_S_FAILURE=1 + - run: + name: Setup Environment Variables + # we need the docker host IP; all ports exported by child containers can be accessed there. + command: echo "export DOCKER_HOST=$(ip -4 addr show docker0 | grep -Po 'inet \K[\d.]+')" >> $BASH_ENV + - run: + echo DOCKER_HOST=$DOCKER_HOST && + make -O -j 3 coverage/sharness_tests.coverprofile test/sharness/test-results/sharness.xml TEST_GENERATE_JUNIT=1 CONTINUE_ON_S_FAILURE=1 DOCKER_HOST=$DOCKER_HOST - run: when: always diff --git a/core/commands/commands_test.go b/core/commands/commands_test.go index 50545418b76..657ed2f4069 100644 --- a/core/commands/commands_test.go +++ b/core/commands/commands_test.go @@ -177,11 +177,19 @@ func TestCommands(t *testing.T) { "/p2p/stream/ls", "/pin", "/pin/add", - "/ping", "/pin/ls", + "/pin/remote", + "/pin/remote/add", + "/pin/remote/ls", + "/pin/remote/rm", + "/pin/remote/service", + "/pin/remote/service/add", + "/pin/remote/service/ls", + "/pin/remote/service/rm", "/pin/rm", "/pin/update", "/pin/verify", + "/ping", "/pubsub", "/pubsub/ls", "/pubsub/peers", diff --git a/core/commands/config.go b/core/commands/config.go index 50af4434357..3931bfc25dc 100644 --- a/core/commands/config.go +++ b/core/commands/config.go @@ -15,8 +15,8 @@ import ( "github.com/ipfs/go-ipfs/repo/fsrepo" "github.com/elgris/jsondiff" - "github.com/ipfs/go-ipfs-cmds" - "github.com/ipfs/go-ipfs-config" + cmds "github.com/ipfs/go-ipfs-cmds" + config "github.com/ipfs/go-ipfs-config" ) // ConfigUpdateOutput is config profile apply command's output @@ -36,6 +36,8 @@ const ( configDryRunOptionName = "dry-run" ) +var tryRemoteServiceApiErr = errors.New("cannot show or change pinning services through this API (try: ipfs pin remote service --help)") + var ConfigCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Get and set ipfs config values.", @@ -86,6 +88,12 @@ Set the value of the 'Datastore.Path' key: default: } + // Temporary fix until we move ApiKey secrets out of the config file + // (remote services are a map, so more advanced blocking is required) + if blocked := inBlockedScope(key, config.RemoteServicesSelector); blocked { + return tryRemoteServiceApiErr + } + cfgRoot, err := cmdenv.GetConfigRoot(env) if err != nil { return err @@ -140,11 +148,29 @@ Set the value of the 'Datastore.Path' key: Type: ConfigField{}, } +// Returns bool to indicate if tested key is in the blocked scope. +// (scope includes parent, direct, and child match) +func inBlockedScope(testKey string, blockedScope string) bool { + blockedScope = strings.ToLower(blockedScope) + roots := strings.Split(strings.ToLower(testKey), ".") + var scope []string + for _, name := range roots { + scope := append(scope, name) + impactedKey := strings.Join(scope, ".") + // blockedScope=foo.bar.BLOCKED should return true + // for parent and child impactedKeys: foo.bar and foo.bar.BLOCKED.subkey + if strings.HasPrefix(impactedKey, blockedScope) || strings.HasPrefix(blockedScope, impactedKey) { + return true + } + } + return false +} + var configShowCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Output config file contents.", ShortDescription: ` -NOTE: For security reasons, this command will omit your private key. If you would like to make a full backup of your config (private key included), you must copy the config file from your repo. +NOTE: For security reasons, this command will omit your private key and remote services. If you would like to make a full backup of your config (private key included), you must copy the config file from your repo. `, }, Type: map[string]interface{}{}, @@ -175,6 +201,11 @@ NOTE: For security reasons, this command will omit your private key. If you woul return err } + err = scrubOptionalValue(cfg, []string{config.PinningTag, config.RemoteServicesTag}) + if err != nil { + return err + } + return cmds.EmitOnce(res, &cfg) }, Encoders: cmds.EncoderMap{ @@ -190,7 +221,17 @@ NOTE: For security reasons, this command will omit your private key. If you woul }, } +// Scrubs value and returns error if missing func scrubValue(m map[string]interface{}, key []string) error { + return scrub(m, key, false) +} + +// Scrubs value and returns no error if missing +func scrubOptionalValue(m map[string]interface{}, key []string) error { + return scrub(m, key, true) +} + +func scrub(m map[string]interface{}, key []string, okIfMissing bool) error { find := func(m map[string]interface{}, k string) (string, interface{}, bool) { lckey := strings.ToLower(k) for mkey, val := range m { @@ -205,7 +246,7 @@ func scrubValue(m map[string]interface{}, key []string) error { cur := m for _, k := range key[:len(key)-1] { foundk, val, ok := find(cur, k) - if !ok { + if !ok && !okIfMissing { return errors.New("failed to find specified key") } @@ -223,7 +264,7 @@ func scrubValue(m map[string]interface{}, key []string) error { } todel, _, ok := find(cur, key[len(key)-1]) - if !ok { + if !ok && !okIfMissing { return fmt.Errorf("%s, not found", strings.Join(key, ".")) } @@ -466,6 +507,9 @@ func replaceConfig(r repo.Repo, file io.Reader) error { if err := json.NewDecoder(file).Decode(&cfg); err != nil { return errors.New("failed to decode file as config") } + + // Handle Identity.PrivKey (secret) + if len(cfg.Identity.PrivKey) != 0 { return errors.New("setting private key with API is not supported") } @@ -482,5 +526,31 @@ func replaceConfig(r repo.Repo, file io.Reader) error { cfg.Identity.PrivKey = pkstr + // Handle Pinning.RemoteServices (ApiKey of each service is secret) + // Note: these settings are opt-in and may be missing + + if len(cfg.Pinning.RemoteServices) != 0 { + return tryRemoteServiceApiErr + } + + // detect if existing config has any remote services defined.. + if remoteServicesTag, err := getConfig(r, config.RemoteServicesSelector); err == nil { + // seems that golang cannot type assert map[string]interface{} to map[string]config.RemotePinningService + // so we have to manually copy the data :-| + if val, ok := remoteServicesTag.Value.(map[string]interface{}); ok { + var services map[string]config.RemotePinningService + jsonString, err := json.Marshal(val) + if err != nil { + return fmt.Errorf("failed to replace config while preserving %s: %s", config.RemoteServicesSelector, err) + } + err = json.Unmarshal(jsonString, &services) + if err != nil { + return fmt.Errorf("failed to replace config while preserving %s: %s", config.RemoteServicesSelector, err) + } + // .. if so, apply them on top of the new config + cfg.Pinning.RemoteServices = services + } + } + return r.SetConfig(&cfg) } diff --git a/core/commands/pin.go b/core/commands/pin/pin.go similarity index 99% rename from core/commands/pin.go rename to core/commands/pin/pin.go index 9d209040a59..a951bac950d 100644 --- a/core/commands/pin.go +++ b/core/commands/pin/pin.go @@ -1,4 +1,4 @@ -package commands +package pin import ( "context" @@ -35,6 +35,7 @@ var PinCmd = &cmds.Command{ "ls": listPinCmd, "verify": verifyPinCmd, "update": updatePinCmd, + "remote": remotePinCmd, }, } diff --git a/core/commands/pin/remotepin.go b/core/commands/pin/remotepin.go new file mode 100644 index 00000000000..12a2639c998 --- /dev/null +++ b/core/commands/pin/remotepin.go @@ -0,0 +1,671 @@ +package pin + +import ( + "context" + "fmt" + "io" + "sort" + "strings" + "text/tabwriter" + "time" + + neturl "net/url" + + "golang.org/x/sync/errgroup" + + cid "github.com/ipfs/go-cid" + cmds "github.com/ipfs/go-ipfs-cmds" + 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" + pinclient "github.com/ipfs/go-pinning-service-http-client" + path "github.com/ipfs/interface-go-ipfs-core/path" + "github.com/libp2p/go-libp2p-core/host" + peer "github.com/libp2p/go-libp2p-core/peer" +) + +var log = logging.Logger("core/commands/cmdenv") + +var remotePinCmd = &cmds.Command{ + Helptext: cmds.HelpText{ + Tagline: "Pin (and unpin) objects to remote pinning service.", + }, + + Subcommands: map[string]*cmds.Command{ + "add": addRemotePinCmd, + "ls": listRemotePinCmd, + "rm": rmRemotePinCmd, + "service": remotePinServiceCmd, + }, +} + +var remotePinServiceCmd = &cmds.Command{ + Helptext: cmds.HelpText{ + Tagline: "Configure remote pinning services.", + }, + + Subcommands: map[string]*cmds.Command{ + "add": addRemotePinServiceCmd, + "ls": lsRemotePinServiceCmd, + "rm": rmRemotePinServiceCmd, + }, +} + +const pinNameOptionName = "name" +const pinCIDsOptionName = "cid" +const pinStatusOptionName = "status" +const pinServiceNameOptionName = "service" +const pinServiceURLOptionName = "url" +const pinServiceKeyOptionName = "key" +const pinServiceStatOptionName = "stat" +const pinBackgroundOptionName = "background" +const pinForceOptionName = "force" + +type RemotePinOutput struct { + Status string + Cid string + Name string +} + +func toRemotePinOutput(ps pinclient.PinStatusGetter) RemotePinOutput { + return RemotePinOutput{ + Name: ps.GetPin().GetName(), + Status: ps.GetStatus().String(), + Cid: ps.GetPin().GetCid().String(), + } +} + +func printRemotePinDetails(w io.Writer, out *RemotePinOutput) { + tw := tabwriter.NewWriter(w, 0, 0, 1, ' ', 0) + defer tw.Flush() + fw := func(k string, v string) { + fmt.Fprintf(tw, "%s:\t%s\n", k, v) + } + fw("CID", out.Cid) + fw("Name", out.Name) + fw("Status", out.Status) +} + +// remote pin commands + +var pinServiceNameOption = cmds.StringOption(pinServiceNameOptionName, "Name of the remote pinning service to use.") + +var addRemotePinCmd = &cmds.Command{ + Helptext: cmds.HelpText{ + Tagline: "Pin object to remote pinning service.", + ShortDescription: "Stores an IPFS object from a given path to a remote pinning service.", + }, + + Arguments: []cmds.Argument{ + cmds.StringArg("ipfs-path", true, false, "Path to object(s) to be pinned."), + }, + Options: []cmds.Option{ + cmds.StringOption(pinNameOptionName, "An optional name for the pin."), + pinServiceNameOption, + cmds.BoolOption(pinBackgroundOptionName, "Add to the queue on the remote service and return immediately (does not wait for pinned status).").WithDefault(false), + }, + Type: RemotePinOutput{}, + Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { + ctx, cancel := context.WithCancel(req.Context) + defer cancel() + + // Get remote service + c, err := getRemotePinServiceFromRequest(req, env) + if err != nil { + return err + } + + // Prepare value for Pin.cid + if len(req.Arguments) != 1 { + return fmt.Errorf("expecting one CID argument") + } + api, err := cmdenv.GetApi(env, req) + if err != nil { + return err + } + rp, err := api.ResolvePath(ctx, path.New(req.Arguments[0])) + if err != nil { + return err + } + + // Prepare Pin.name + opts := []pinclient.AddOption{} + if name, nameFound := req.Options[pinNameOptionName]; nameFound { + nameStr := name.(string) + opts = append(opts, pinclient.PinOpts.WithName(nameStr)) + } + + // Prepare Pin.origins + // Add own multiaddrs to the 'origins' array, so Pinning Service can + // use that as a hint and connect back to us (if possible) + node, err := cmdenv.GetNode(env) + if err != nil { + return err + } + if node.PeerHost != nil { + addrs, err := peer.AddrInfoToP2pAddrs(host.InfoFromHost(node.PeerHost)) + if err != nil { + return err + } + opts = append(opts, pinclient.PinOpts.WithOrigins(addrs...)) + } + + // Execute remote pin request + // TODO: fix panic when pinning service is down + ps, err := c.Add(ctx, rp.Cid(), opts...) + if err != nil { + return err + } + + // Act on PinStatus.delegates + // If Pinning Service returned any delegates, proactively try to + // connect to them to facilitate data exchange without waiting for DHT + // lookup + for _, d := range ps.GetDelegates() { + // TODO: confirm this works as expected + p, err := peer.AddrInfoFromP2pAddr(d) + if err != nil { + return err + } + if err := api.Swarm().Connect(ctx, *p); err != nil { + log.Infof("error connecting to remote pin delegate %v : %w", d, err) + } + } + + // Block unless --background=true is passed + if !req.Options[pinBackgroundOptionName].(bool) { + requestId := ps.GetRequestId() + for { + ps, err = c.GetStatusByID(ctx, requestId) + if err != nil { + return fmt.Errorf("failed to check pin status for requestid=%q due to error: %v", requestId, err) + } + if ps.GetRequestId() != requestId { + return fmt.Errorf("failed to check pin status for requestid=%q, remote service sent unexpected requestid=%q", requestId, ps.GetRequestId()) + } + s := ps.GetStatus() + if s == pinclient.StatusPinned { + break + } + if s == pinclient.StatusFailed { + return fmt.Errorf("remote service failed to pin requestid=%q", requestId) + } + tmr := time.NewTimer(time.Second / 2) + select { + case <-tmr.C: + case <-ctx.Done(): + return fmt.Errorf("waiting for pin interrupted, requestid=%q remains on remote service", requestId) + } + } + } + + return res.Emit(toRemotePinOutput(ps)) + }, + Encoders: cmds.EncoderMap{ + cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *RemotePinOutput) error { + printRemotePinDetails(w, out) + return nil + }), + }, +} + +var listRemotePinCmd = &cmds.Command{ + Helptext: cmds.HelpText{ + Tagline: "List objects pinned to remote pinning service.", + ShortDescription: ` +Returns a list of objects that are pinned to a remote pinning service. +`, + LongDescription: ` +Returns a list of objects that are pinned to a remote pinning service. +`, + }, + + Arguments: []cmds.Argument{}, + Options: []cmds.Option{ + cmds.StringOption(pinNameOptionName, "Return pins objects with names that contain provided value (case-sensitive, exact match)."), + cmds.StringsOption(pinCIDsOptionName, "Return only pin objects for the specified CID(s); optional, comma separated."), + cmds.StringsOption(pinStatusOptionName, "Return only pin objects with the specified statuses (queued,pinning,pinned,failed)").WithDefault([]string{"pinned"}), + pinServiceNameOption, + }, + Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { + ctx, cancel := context.WithCancel(req.Context) + defer cancel() + + c, err := getRemotePinServiceFromRequest(req, env) + if err != nil { + return err + } + + psCh, errCh, err := lsRemote(ctx, req, c) + if err != nil { + return err + } + + for ps := range psCh { + if err := res.Emit(toRemotePinOutput(ps)); err != nil { + return err + } + } + + return <-errCh + }, + Type: RemotePinOutput{}, + Encoders: cmds.EncoderMap{ + cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *RemotePinOutput) error { + // pin remote ls produces a flat output similar to legacy pin ls + fmt.Fprintf(w, "%s\t%s\t%s\n", out.Cid, out.Status, out.Name) + return nil + }), + }, +} + +// Executes GET /pins/?query-with-filters +func lsRemote(ctx context.Context, req *cmds.Request, c *pinclient.Client) (chan pinclient.PinStatusGetter, chan error, error) { + opts := []pinclient.LsOption{} + if name, nameFound := req.Options[pinNameOptionName]; nameFound { + nameStr := name.(string) + opts = append(opts, pinclient.PinOpts.FilterName(nameStr)) + } + + if cidsRaw, cidsFound := req.Options[pinCIDsOptionName]; cidsFound { + cidsRawArr := cidsRaw.([]string) + parsedCIDs := []cid.Cid{} + for _, rawCID := range flattenCommaList(cidsRawArr) { + parsedCID, err := cid.Decode(rawCID) + if err != nil { + return nil, nil, fmt.Errorf("CID %q cannot be parsed: %v", rawCID, err) + } + parsedCIDs = append(parsedCIDs, parsedCID) + } + opts = append(opts, pinclient.PinOpts.FilterCIDs(parsedCIDs...)) + } + if statusRaw, statusFound := req.Options[pinStatusOptionName]; statusFound { + statusRawArr := statusRaw.([]string) + parsedStatuses := []pinclient.Status{} + for _, rawStatus := range flattenCommaList(statusRawArr) { + s := pinclient.Status(rawStatus) + if s.String() == string(pinclient.StatusUnknown) { + return nil, nil, fmt.Errorf("status %q is not valid", rawStatus) + } + parsedStatuses = append(parsedStatuses, s) + } + opts = append(opts, pinclient.PinOpts.FilterStatus(parsedStatuses...)) + } + + psCh, errCh := c.Ls(ctx, opts...) + + return psCh, errCh, nil +} + +func flattenCommaList(list []string) []string { + flatList := list[:0] + for _, s := range list { + flatList = append(flatList, strings.Split(s, ",")...) + } + return flatList +} + +var rmRemotePinCmd = &cmds.Command{ + Helptext: cmds.HelpText{ + Tagline: "Remove pinned objects from remote pinning service.", + ShortDescription: ` +Removes the pin from the given object allowing it to be garbage +collected if needed. +`, + }, + + Arguments: []cmds.Argument{}, + Options: []cmds.Option{ + pinServiceNameOption, + cmds.StringOption(pinNameOptionName, "Remove pin objects with names that contain provided value (case-sensitive, exact match)."), + cmds.StringsOption(pinCIDsOptionName, "Remove only pin objects for the specified CID(s)."), + cmds.StringsOption(pinStatusOptionName, "Remove only pin objects with the specified statuses (queued,pinning,pinned,failed).").WithDefault([]string{"pinned"}), + cmds.BoolOption(pinForceOptionName, "Remove multiple pins without confirmation.").WithDefault(false), + }, + Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { + ctx, cancel := context.WithCancel(req.Context) + defer cancel() + + c, err := getRemotePinServiceFromRequest(req, env) + if err != nil { + return err + } + + rmIDs := []string{} + if len(req.Arguments) == 0 { + psCh, errCh, err := lsRemote(ctx, req, c) + if err != nil { + return err + } + for ps := range psCh { + rmIDs = append(rmIDs, ps.GetRequestId()) + } + if err = <-errCh; err != nil { + return fmt.Errorf("error while listing remote pins: %v", err) + } + + if len(rmIDs) > 1 && !req.Options[pinForceOptionName].(bool) { + return fmt.Errorf("multiple remote pins are matching this query, add --force to confirm the bulk removal") + } + } else { + return fmt.Errorf("unexpected argument %q", req.Arguments[0]) + } + + for _, rmID := range rmIDs { + if err := c.DeleteByID(ctx, rmID); err != nil { + return fmt.Errorf("removing pin identified by requestid=%q failed: %v", rmID, err) + } + } + return nil + }, +} + +// remote service commands + +var addRemotePinServiceCmd = &cmds.Command{ + Helptext: cmds.HelpText{ + Tagline: "Add remote pinning service.", + ShortDescription: "Add a credentials for access to a remote pinning service.", + }, + Arguments: []cmds.Argument{ + cmds.StringArg(pinServiceNameOptionName, true, false, "Service name."), + cmds.StringArg(pinServiceURLOptionName, true, false, "Service URL."), + cmds.StringArg(pinServiceKeyOptionName, true, false, "Service key."), + }, + Type: nil, + Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { + cfgRoot, err := cmdenv.GetConfigRoot(env) + if err != nil { + return err + } + repo, err := fsrepo.Open(cfgRoot) + if err != nil { + return err + } + defer repo.Close() + + if len(req.Arguments) < 3 { + return fmt.Errorf("expecting three arguments: service name, url and key") + } + + name := req.Arguments[0] + url := strings.TrimSuffix(req.Arguments[1], "/pins") // fix /pins/pins :-) + key := req.Arguments[2] + + u, err := neturl.ParseRequestURI(url) + if err != nil || !strings.HasPrefix(u.Scheme, "http") { + return fmt.Errorf("service url must be a valid HTTP URL") + } + + cfg, err := repo.Config() + if err != nil { + return err + } + if cfg.Pinning.RemoteServices != nil { + if _, present := cfg.Pinning.RemoteServices[name]; present { + return fmt.Errorf("service already present") + } + } else { + cfg.Pinning.RemoteServices = map[string]config.RemotePinningService{} + } + + cfg.Pinning.RemoteServices[name] = config.RemotePinningService{ + Api: config.RemotePinningServiceApi{ + Endpoint: url, + Key: key, + }, + } + + return repo.SetConfig(cfg) + }, +} + +var rmRemotePinServiceCmd = &cmds.Command{ + Helptext: cmds.HelpText{ + Tagline: "Remove remote pinning service.", + ShortDescription: "Remove credentials for access to a remote pinning service.", + }, + Arguments: []cmds.Argument{ + cmds.StringArg("remote-pin-service", true, false, "Name of remote pinning service to remove."), + }, + Options: []cmds.Option{}, + Type: nil, + Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { + cfgRoot, err := cmdenv.GetConfigRoot(env) + if err != nil { + return err + } + repo, err := fsrepo.Open(cfgRoot) + if err != nil { + return err + } + defer repo.Close() + + if len(req.Arguments) != 1 { + return fmt.Errorf("expecting one argument: name") + } + name := req.Arguments[0] + + cfg, err := repo.Config() + if err != nil { + return err + } + if cfg.Pinning.RemoteServices != nil { + delete(cfg.Pinning.RemoteServices, name) + } + return repo.SetConfig(cfg) + }, +} + +var lsRemotePinServiceCmd = &cmds.Command{ + Helptext: cmds.HelpText{ + Tagline: "List remote pinning services.", + ShortDescription: "List remote pinning services.", + }, + Arguments: []cmds.Argument{}, + Options: []cmds.Option{ + cmds.BoolOption(pinServiceStatOptionName, "Try to fetch and display current pin count on remote service (queued/pinning/pinned/failed).").WithDefault(false), + }, + Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { + ctx, cancel := context.WithCancel(req.Context) + defer cancel() + + cfgRoot, err := cmdenv.GetConfigRoot(env) + if err != nil { + return err + } + repo, err := fsrepo.Open(cfgRoot) + if err != nil { + return err + } + defer repo.Close() + + cfg, err := repo.Config() + if err != nil { + return err + } + if cfg.Pinning.RemoteServices == nil { + return nil // no pinning services added yet + } + services := cfg.Pinning.RemoteServices + result := PinServicesList{make([]ServiceDetails, 0, len(services))} + for svcName, svcConfig := range services { + svcDetails := ServiceDetails{svcName, svcConfig.Api.Endpoint, nil} + + // if --pin-count is passed, we try to fetch pin numbers from remote service + if req.Options[pinServiceStatOptionName].(bool) { + lsRemotePinCount := func(ctx context.Context, env cmds.Environment, svcName string) (*PinCount, error) { + c, err := getRemotePinService(env, svcName) + if err != nil { + return nil, err + } + // we only care about total count, so requesting smallest batch + batch := pinclient.PinOpts.Limit(1) + fs := pinclient.PinOpts.FilterStatus + + statuses := []pinclient.Status{ + pinclient.StatusQueued, + pinclient.StatusPinning, + pinclient.StatusPinned, + pinclient.StatusFailed, + } + + g, ctx := errgroup.WithContext(ctx) + pc := &PinCount{} + + for _, s := range statuses { + status := s // lol https://golang.org/doc/faq#closures_and_goroutines + g.Go(func() error { + _, n, err := c.LsBatchSync(ctx, batch, fs(status)) + if err != nil { + return err + } + switch status { + case pinclient.StatusQueued: + pc.Queued = n + case pinclient.StatusPinning: + pc.Pinning = n + case pinclient.StatusPinned: + pc.Pinned = n + case pinclient.StatusFailed: + pc.Failed = n + } + return nil + }) + } + if err := g.Wait(); err != nil { + return nil, err + } + + return pc, nil + } + + pinCount, err := lsRemotePinCount(ctx, env, svcName) + + // PinCount is present only if we were able to fetch counts. + // We don't want to break listing of services so this is best-effort. + // (verbose err is returned by 'pin remote ls', if needed) + svcDetails.Stat = &Stat{} + if err == nil { + svcDetails.Stat.Status = "valid" + svcDetails.Stat.PinCount = pinCount + } else { + svcDetails.Stat.Status = "invalid" + } + } + result.RemoteServices = append(result.RemoteServices, svcDetails) + } + sort.Sort(result) + return cmds.EmitOnce(res, &result) + }, + Type: PinServicesList{}, + Encoders: cmds.EncoderMap{ + cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, list *PinServicesList) error { + tw := tabwriter.NewWriter(w, 1, 2, 1, ' ', 0) + withStat := req.Options[pinServiceStatOptionName].(bool) + for _, s := range list.RemoteServices { + if withStat { + stat := s.Stat.Status + pc := s.Stat.PinCount + if s.Stat.PinCount != nil { + stat = fmt.Sprintf("%d/%d/%d/%d", pc.Queued, pc.Pinning, pc.Pinned, pc.Failed) + } + fmt.Fprintf(tw, "%s\t%s\t%s\n", s.Service, s.ApiEndpoint, stat) + } else { + fmt.Fprintf(tw, "%s\t%s\n", s.Service, s.ApiEndpoint) + } + } + tw.Flush() + return nil + }), + }, +} + +type ServiceDetails struct { + Service string + ApiEndpoint string + Stat *Stat `json:",omitempty"` // present only when --stat not passed +} + +type Stat struct { + Status string + PinCount *PinCount `json:",omitempty"` // missing when --stat is passed but the service is offline +} + +type PinCount struct { + Queued int + Pinning int + Pinned int + Failed int +} + +// Struct returned by ipfs pin remote service ls --enc=json | jq +type PinServicesList struct { + RemoteServices []ServiceDetails +} + +func (l PinServicesList) Len() int { + return len(l.RemoteServices) +} + +func (l PinServicesList) Swap(i, j int) { + s := l.RemoteServices + s[i], s[j] = s[j], s[i] +} + +func (l PinServicesList) Less(i, j int) bool { + s := l.RemoteServices + return s[i].Service < s[j].Service +} + +func getRemotePinServiceFromRequest(req *cmds.Request, env cmds.Environment) (*pinclient.Client, error) { + service, serviceFound := req.Options[pinServiceNameOptionName] + if !serviceFound { + return nil, fmt.Errorf("a service name must be passed") + } + + serviceStr := service.(string) + var err error + c, err := getRemotePinService(env, serviceStr) + if err != nil { + return nil, err + } + + return c, nil +} + +func getRemotePinService(env cmds.Environment, name string) (*pinclient.Client, error) { + if name == "" { + return nil, fmt.Errorf("remote pinning service name not specified") + } + url, key, err := getRemotePinServiceInfo(env, name) + if err != nil { + return nil, err + } + return pinclient.NewClient(url, key), nil +} + +func getRemotePinServiceInfo(env cmds.Environment, name string) (url, key string, err error) { + cfgRoot, err := cmdenv.GetConfigRoot(env) + if err != nil { + return "", "", err + } + repo, err := fsrepo.Open(cfgRoot) + if err != nil { + return "", "", err + } + defer repo.Close() + cfg, err := repo.Config() + if err != nil { + return "", "", err + } + if cfg.Pinning.RemoteServices == nil { + return "", "", fmt.Errorf("service not known") + } + service, present := cfg.Pinning.RemoteServices[name] + if !present { + return "", "", fmt.Errorf("service not known") + } + return service.Api.Endpoint, service.Api.Key, nil +} diff --git a/core/commands/root.go b/core/commands/root.go index b9a8dc40909..1440c31b7eb 100644 --- a/core/commands/root.go +++ b/core/commands/root.go @@ -7,6 +7,7 @@ import ( dag "github.com/ipfs/go-ipfs/core/commands/dag" name "github.com/ipfs/go-ipfs/core/commands/name" ocmd "github.com/ipfs/go-ipfs/core/commands/object" + "github.com/ipfs/go-ipfs/core/commands/pin" unixfs "github.com/ipfs/go-ipfs/core/commands/unixfs" cmds "github.com/ipfs/go-ipfs-cmds" @@ -136,7 +137,7 @@ var rootSubcommands = map[string]*cmds.Command{ "mount": MountCmd, "name": name.NameCmd, "object": ocmd.ObjectCmd, - "pin": PinCmd, + "pin": pin.PinCmd, "ping": PingCmd, "p2p": P2PCmd, "refs": RefsCmd, diff --git a/docs/config.md b/docs/config.md index 938477b719d..2ea82bca39a 100644 --- a/docs/config.md +++ b/docs/config.md @@ -176,6 +176,11 @@ does (e.g, `"1d2h4m40.01s"`). - [`Mounts.IPFS`](#mountsipfs) - [`Mounts.IPNS`](#mountsipns) - [`Mounts.FuseAllowOther`](#mountsfuseallowother) +- [`Pinning`](#pinning) + - [`Pinning.RemoteServices`](#pinningremoteservices) + - [`Pinning.RemoteServices.API`](#pinningremoteservices-api) + - [`Pinning.RemoteServices.API.Endpoint`](#pinningremoteservices-apiendpoint) + - [`Pinning.RemoteServices.API.Key`](#pinningremoteservices-apikey) - [`Pubsub`](#pubsub) - [`Pubsub.Router`](#pubsubrouter) - [`Pubsub.DisableSigning`](#pubsubdisablesigning) @@ -813,6 +818,55 @@ Type: `string` (filesystem path) Sets the FUSE allow other option on the mountpoint. +## `Pinning` + +Pinning configures the options available for pinning content +(i.e. keeping content longer term instead of as temporarily cached storage). + +### `Pinning.RemoteServices` + +`RemoteServices` maps a name for a remote pinning service to its configuration. + +A remote pinning service is a remote service that exposes an API for managing +that service's interest in longer term data storage. + +The exposed API conforms to the specification defined at +https://ipfs.github.io/pinning-services-api-spec/ + +#### `Pinning.RemoteServices: API` + +Contains information relevant to utilizing the remote pinning service + +Example: +```json +{ + "Pinning": { + "RemoteServices": { + "myPinningService": { + "API" : { + "Endpoint" : "https://pinningservice.tld:1234/my/api/path", + "Key" : "someOpaqueKey" + } + } + } + } +} +``` + +##### `Pinning.RemoteServices: API.Endpoint` + +The HTTP(S) endpoint through which to access the pinning service + +Example: "https://pinningservice.tld:1234/my/api/path" + +Type: `string` + +##### `Pinning.RemoteServices: API.Key` + +The key through which access to the pinning service is granted + +Type: `string` + ## `Pubsub` Pubsub configures the `ipfs pubsub` subsystem. To use, it must be enabled by diff --git a/go.mod b/go.mod index 3419cb7d47e..208ec025780 100644 --- a/go.mod +++ b/go.mod @@ -30,8 +30,8 @@ require ( github.com/ipfs/go-graphsync v0.5.1 github.com/ipfs/go-ipfs-blockstore v0.1.4 github.com/ipfs/go-ipfs-chunker v0.0.5 - github.com/ipfs/go-ipfs-cmds v0.4.0 - github.com/ipfs/go-ipfs-config v0.9.0 + github.com/ipfs/go-ipfs-cmds v0.5.0 + github.com/ipfs/go-ipfs-config v0.11.0 github.com/ipfs/go-ipfs-ds-help v0.1.1 github.com/ipfs/go-ipfs-exchange-interface v0.0.1 github.com/ipfs/go-ipfs-exchange-offline v0.0.1 @@ -51,6 +51,7 @@ require ( github.com/ipfs/go-metrics-prometheus v0.0.2 github.com/ipfs/go-mfs v0.1.2 github.com/ipfs/go-path v0.0.8 + github.com/ipfs/go-pinning-service-http-client v0.1.0 github.com/ipfs/go-unixfs v0.2.4 github.com/ipfs/go-verifcid v0.0.1 github.com/ipfs/interface-go-ipfs-core v0.4.0 @@ -104,6 +105,7 @@ require ( go.uber.org/zap v1.16.0 golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect + golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 ) diff --git a/go.sum b/go.sum index a425b5e0bd4..03a445461ce 100644 --- a/go.sum +++ b/go.sum @@ -35,7 +35,6 @@ github.com/Kubuxu/go-os-helper v0.0.1 h1:EJiD2VUQyh5A9hWJLmc6iWg6yIcJ7jpBcwC8GMG github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/Stebalien/go-bitfield v0.0.0-20180330043415-076a62f9ce6e/go.mod h1:3oM7gXIttpYDAJXpVNnSCiUMYBLIZ6cb1t+Ip982MRo= 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/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= @@ -142,7 +141,6 @@ github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 h1:BBso6MBKW github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5/go.mod h1:JpoxHjuQauoxiFMl1ie8Xc/7TfLuMZ5eOCONd1sUBHg= 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/fd/go-nat v1.0.0/go.mod h1:BTBu/CKvMmOMUPkKVef1pngt2WFH/lg7E6yQnulfp6E= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6 h1:u/UEqS66A5ckRmS4yNpjmVH56sVtS/RfclBAYocb4as= github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6/go.mod h1:1i71OnUq3iUe1ma7Lr6yG6/rjvM3emb6yoL7xLFzcVQ= @@ -253,7 +251,6 @@ github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:Fecb github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= 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/gxed/pubsub v0.0.0-20180201040156-26ebdf44f824/go.mod h1:OiEWyHgK+CWrmOlVquHaIK1vhpUJydC9m0Je6mhaiNE= 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= @@ -268,7 +265,6 @@ github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uG 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/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/huin/goupnp v0.0.0-20180415215157-1395d1447324/go.mod h1:MZ2ZmwcBpvOoJ22IJsc7va19ZwoheaBk43rKg12SKag= github.com/huin/goupnp v1.0.0 h1:wg75sLpL6DZqwHQN6E1Cfk6mtfzS45z8OV+ic+DtHRo= github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= @@ -277,7 +273,6 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt 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-bitswap v0.0.3/go.mod h1:jadAZYsP/tcRMl47ZhFxhaNuDQoXawT8iHMg+iFoQbg= 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= @@ -288,7 +283,6 @@ github.com/ipfs/go-bitswap v0.3.3/go.mod h1:AyWWfN3moBzQX0banEtfKOfbXb3ZeoOeXnZG 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-blockservice v0.0.3/go.mod h1:/NNihwTi6V2Yr6g8wBI+BSwPuURpBRMtYNGrlxZ8KuI= 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= @@ -368,10 +362,10 @@ github.com/ipfs/go-ipfs-chunker v0.0.1 h1:cHUUxKFQ99pozdahi+uSC/3Y6HeRpi9oTeUHbE 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.4.0 h1:xUavIxA9Ts8U6PAHmQBvDGMlGfUrQ13Rymd+5t8LIF4= -github.com/ipfs/go-ipfs-cmds v0.4.0/go.mod h1:ZgYiWVnCk43ChwoH8hAmI1IRbuVtq3GSTHwtRB/Kqhk= -github.com/ipfs/go-ipfs-config v0.9.0 h1:qTXJ9CyOyQv1LFJUMysxz8fi6RxxnP9QqcmiobuANvw= -github.com/ipfs/go-ipfs-config v0.9.0/go.mod h1:GQUxqb0NfkZmEU92PxqqqLVVFTLpoGGUlBaTyDaAqrE= +github.com/ipfs/go-ipfs-cmds v0.5.0 h1:T1ZT6Qu3IUCp6FgU2IzVtvGLaexEWo9q13+S5ic+Q5Y= +github.com/ipfs/go-ipfs-cmds v0.5.0/go.mod h1:ZgYiWVnCk43ChwoH8hAmI1IRbuVtq3GSTHwtRB/Kqhk= +github.com/ipfs/go-ipfs-config v0.11.0 h1:w4t2pz415Gtg6MTUKAq06C7ezC59/Us+k3+n1Tje+wg= +github.com/ipfs/go-ipfs-config v0.11.0/go.mod h1:Ei/FLgHGTdPyqCPK0oPCwGTe8VSnsjJjx7HZqUb6Ry0= 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= @@ -383,11 +377,9 @@ github.com/ipfs/go-ipfs-exchange-interface v0.0.1 h1:LJXIo9W7CAmugqI+uofioIpRb6r 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-offline v0.0.1/go.mod h1:WhHSFCVYX36H/anEKQboAzpUws3x7UeEGkzQc3iNkM0= -github.com/ipfs/go-ipfs-files v0.0.2/go.mod h1:INEFm0LL2LWXBhNJ2PMIIb2w45hpXgPjNoE7yA8Y1d4= 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= -github.com/ipfs/go-ipfs-flags v0.0.1/go.mod h1:RnXBb9WV53GSfTrSDVK61NLTFKvWc60n+K9EgCDh+rA= github.com/ipfs/go-ipfs-pinner v0.1.0 h1:rjSrbUDYd1YYHZ5dOgu+QEOuLcU0m/2a/brcxC/ReeU= github.com/ipfs/go-ipfs-pinner v0.1.0/go.mod h1:EzyyaWCWeZJ/he9cDBH6QrEkSuRqTRWMmCoyNkylTTg= github.com/ipfs/go-ipfs-posinfo v0.0.1 h1:Esoxj+1JgSjX0+ylc0hUmJCOv6V2vFoZiETLR6OtpRs= @@ -404,7 +396,6 @@ github.com/ipfs/go-ipfs-util v0.0.1 h1:Wz9bL2wB2YBJqggkA4dD7oSmqB4cAnpNbGrlHJulv 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.1/go.mod h1:RXHr8s4k0NE0TKhnrxqZC9M888QfsBN9rhS5NjfKzY8= github.com/ipfs/go-ipld-cbor v0.0.2/go.mod h1:wTBtrQZA3SoFKMVkp6cn6HMRteIB1VsmHA0AQFOn7Nc= github.com/ipfs/go-ipld-cbor v0.0.3 h1:ENsxvybwkmke7Z/QJOmeJfoguj6GH3Y0YOaGrfy9Q0I= github.com/ipfs/go-ipld-cbor v0.0.3/go.mod h1:wTBtrQZA3SoFKMVkp6cn6HMRteIB1VsmHA0AQFOn7Nc= @@ -441,7 +432,6 @@ 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 h1:G4TtqN+V9y9HY9TA6BwbCVyyBZ2B9MbCjR2MtGx8FR0= github.com/ipfs/go-log/v2 v2.1.1/go.mod h1:2v2nsGfZsvvAJz13SyFzf9ObaqwHiHxsPLEHntrv9KM= -github.com/ipfs/go-merkledag v0.0.3/go.mod h1:Oc5kIXLHokkE1hWGMBHw+oxehkAaTOqtEb7Zbh6BhLA= 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 h1:aMdkK9G1hEeNvn3VXfiEMLY0iJnbiQQUHnM0HFJREsE= @@ -458,7 +448,6 @@ github.com/ipfs/go-metrics-prometheus v0.0.2 h1:9i2iljLg12S78OhC6UAiXi176xvQGiZa 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-path v0.0.3/go.mod h1:zIRQUez3LuQIU25zFjC2hpBTHimWx7VK5bjZgRLbbdo= github.com/ipfs/go-path v0.0.7 h1:H06hKMquQ0aYtHiHryOMLpQC1qC3QwXwkahcEVD51Ho= github.com/ipfs/go-path v0.0.7/go.mod h1:6KTKmeRnBXgqrTvzFrPV3CamxcgvXX/4z79tfAd2Sno= github.com/ipfs/go-path v0.0.8 h1:R0k6t9x/pa+g8qzl5apQIPurJFozXhopks3iw3MX+jU= @@ -468,14 +457,13 @@ github.com/ipfs/go-peertaskqueue v0.1.0/go.mod h1:Jmk3IyCcfl1W3jTW3YpghSwSEC6IJ3 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-unixfs v0.0.4/go.mod h1:eIo/p9ADu/MFOuyxzwU+Th8D6xoxU//r590vUpWyfz8= +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-unixfs v0.1.0/go.mod h1:lysk5ELhOso8+Fed9U1QTGey2ocsfaZ18h0NCO2Fj9s= 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-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.3.0 h1:oZdLLfh256gPGcYPURjivj/lv296GIcr8mUqZUnXOEI= -github.com/ipfs/interface-go-ipfs-core v0.3.0/go.mod h1:Tihp8zxGpUeE3Tokr94L6zWZZdkRQvG5TL6i9MuNE+s= 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/ipld/go-car v0.1.1-0.20201015032735-ff6ccdc46acc h1:BdI33Q56hLWG9Ef0WbQ7z+dwmbRYhTb45SMjw0RudbQ= @@ -486,7 +474,6 @@ github.com/ipld/go-ipld-prime v0.5.1-0.20201021195245-109253e8a018/go.mod h1:0xE github.com/ipld/go-ipld-prime-proto v0.0.0-20200922192210-9a2bfd4440a6/go.mod h1:3pHYooM9Ea65jewRwrb2u5uHZCNkNTe9ABsVB+SrkH0= github.com/ipld/go-ipld-prime-proto v0.1.0 h1:j7gjqrfwbT4+gXpHwEx5iMssma3mnctC7YaCimsFP70= github.com/ipld/go-ipld-prime-proto v0.1.0/go.mod h1:11zp8f3sHVgIqtb/c9Kr5ZGqpnCLF1IVTNOez9TopzE= -github.com/jackpal/gateway v1.0.4/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQetPfnjA= github.com/jackpal/gateway v1.0.5 h1:qzXWUJfuMdlLMtt0a3Dgt+xkWQiA5itDEITVJtuSwMc= github.com/jackpal/gateway v1.0.5/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQetPfnjA= github.com/jackpal/go-nat-pmp v1.0.1 h1:i0LektDkO1QlrTm/cSuP+PyBCDnYvjPLGl4LdWEMiaA= @@ -551,7 +538,6 @@ github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoR 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.1/go.mod h1:nc9vud7inQ+d6SO0I/6dSWrdMnHnzZNHeyUQqrAJulE= 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 h1:aqGmto+ttL/uJgX0JtQI0tD21CIEy5eYd1Hlp0juHY0= github.com/libp2p/go-conn-security-multistream v0.1.0/go.mod h1:aw6eD7LOsHEX7+2hJkDxw1MteijaVcI+/eP2/x3J1xc= @@ -567,7 +553,6 @@ github.com/libp2p/go-flow-metrics v0.0.2 h1:U5TvqfoyR6GVRM+bC15Ux1ltar1kbj6Zw6xO github.com/libp2p/go-flow-metrics v0.0.2/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= 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.2/go.mod h1:Qu8bWqFXiocPloabFGUcVG4kk94fLvfC8mWTDdFC9wE= 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= @@ -582,7 +567,6 @@ github.com/libp2p/go-libp2p v0.12.0 h1:+xai9RQnQ9l5elFOKvp5wRyjyWisSwEx+6nU2+onp github.com/libp2p/go-libp2p v0.12.0/go.mod h1:FpHZrfC1q7nA8jitvdjKBDF31hguaC676g/nT9PgQM0= github.com/libp2p/go-libp2p-asn-util v0.0.0-20200825225859-85005c6cf052 h1:BM7aaOF7RpmNn9+9g6uTjGJ0cTzWr5j9i9IKeun2M8U= 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-autonat v0.0.2/go.mod h1:fs71q5Xk+pdnKU014o2iq1RhMs9/PMaG5zXRFNnIIT4= github.com/libp2p/go-libp2p-autonat v0.0.6/go.mod h1:uZneLdOkZHro35xIhpbtTzLlgYturpu4J5+0cZK3MqE= github.com/libp2p/go-libp2p-autonat v0.1.0 h1:aCWAu43Ri4nU0ZPO7NyLzUvvfqd0nE3dX0R/ZGYVgOU= github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8= @@ -602,7 +586,6 @@ github.com/libp2p/go-libp2p-blankhost v0.1.4 h1:I96SWjR4rK9irDHcHq3XHN6hawCRTPUA 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-circuit v0.0.1/go.mod h1:Dqm0s/BiV63j8EEAs8hr1H5HudqvCAeXxDyic59lCwE= 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 h1:Phzbmrg3BkVzbqd4ZZ149JxCuUWu2wZcXf/Kr6hZJj8= @@ -650,7 +633,6 @@ github.com/libp2p/go-libp2p-crypto v0.0.1/go.mod h1:yJkNyDmO341d5wwXxDUGO0LykUVT github.com/libp2p/go-libp2p-crypto v0.0.2/go.mod h1:eETI5OUfBnvARGOHrJz2eWNyTUxEGZnBxMcbUjfIj4I= github.com/libp2p/go-libp2p-crypto v0.1.0 h1:k9MFy+o2zGDNGsaoZl0MA3iZ75qXxr9OOoAZF+sD5OQ= github.com/libp2p/go-libp2p-crypto v0.1.0/go.mod h1:sPUokVISZiy+nNuTTH/TY+leRSxnFj/2GLjtOTW90hI= -github.com/libp2p/go-libp2p-discovery v0.0.1/go.mod h1:ZkkF9xIFRLA1xCc7bstYFkd80gBGK8Fc1JqGoU2i+zI= github.com/libp2p/go-libp2p-discovery v0.0.5/go.mod h1:YtF20GUxjgoKZ4zmXj8j3Nb2TUSBHFlOCetzYdbZL5I= github.com/libp2p/go-libp2p-discovery v0.1.0 h1:j+R6cokKcGbnZLf4kcNwpx6mDEUPF3N6SrqMymQhmvs= github.com/libp2p/go-libp2p-discovery v0.1.0/go.mod h1:4F/x+aldVHjHDHuX85x1zWoFTGElt8HnoDzwkFZm29g= @@ -688,7 +670,6 @@ github.com/libp2p/go-libp2p-mplex v0.2.3 h1:2zijwaJvpdesST2MXpI5w9wWFRgYtMcpRX7r 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 h1:CZyqqKP0BSGQyPLvpRQougbfXaaaJZdGgzhCpJNuNSk= github.com/libp2p/go-libp2p-mplex v0.3.0/go.mod h1:l9QWxRbbb5/hQMECEb908GbS9Sm2UAR2KFZKUJEynEs= -github.com/libp2p/go-libp2p-nat v0.0.2/go.mod h1:QrjXQSD5Dj4IJOdEcjHRkWTSomyxRo6HnUkf/TfQpLQ= github.com/libp2p/go-libp2p-nat v0.0.4 h1:+KXK324yaY701On8a0aGjTnw8467kW3ExKcqW2wwmyw= github.com/libp2p/go-libp2p-nat v0.0.4/go.mod h1:N9Js/zVtAXqaeT99cXgTV9e75KpnWCvVOiGzlcHmBbY= github.com/libp2p/go-libp2p-nat v0.0.5 h1:/mH8pXFVKleflDL1YwqMg27W9GD8kjEx7NY0P6eGc98= @@ -743,7 +724,6 @@ github.com/libp2p/go-libp2p-record v0.1.3/go.mod h1:yNUff/adKIfPnYQXgp6FQmNu3gLJ 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= -github.com/libp2p/go-libp2p-secio v0.0.1/go.mod h1:IdG6iQybdcYmbTzxp4J5dwtUEDTOvZrT0opIDVNPrJs= 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 h1:ywzZBsWEEz2KNTn5RtzauEDq5RFEefPsttXYwAWqHng= @@ -752,7 +732,6 @@ github.com/libp2p/go-libp2p-secio v0.2.1 h1:eNWbJTdyPA7NxhP7J3c5lT97DC5d+u+Ildkg 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.1/go.mod h1:mh+KZxkbd3lQnveQ3j2q60BM1Cw2mX36XXQqwfPOShs= 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.2 h1:T4hUpgEs2r371PweU3DuH7EOmBIdTBCwWs+FLcgx3bQ= @@ -778,9 +757,7 @@ github.com/libp2p/go-libp2p-testing v0.3.0/go.mod h1:efZkql4UZ7OVsEfaxNHZPzIehts github.com/libp2p/go-libp2p-tls v0.1.3 h1:twKMhMu44jQO+HgQK9X8NHO5HkeJu2QbhLzLJpa8oNM= github.com/libp2p/go-libp2p-tls v0.1.3/go.mod h1:wZfuewxOndz5RTnCAxFliGjvYSDA40sKitV4c50uI1M= github.com/libp2p/go-libp2p-transport v0.0.1/go.mod h1:UzbUs9X+PHOSw7S3ZmeOxfnwaQY5vGDzZmKPod3N3tk= -github.com/libp2p/go-libp2p-transport v0.0.4/go.mod h1:StoY3sx6IqsP6XKoabsPnHCwqKXWUMWU7Rfcsubee/A= github.com/libp2p/go-libp2p-transport v0.0.5/go.mod h1:StoY3sx6IqsP6XKoabsPnHCwqKXWUMWU7Rfcsubee/A= -github.com/libp2p/go-libp2p-transport-upgrader v0.0.1/go.mod h1:NJpUAgQab/8K6K0m+JmZCe5RUXG10UMEx4kWe9Ipj5c= 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 h1:PZMS9lhjK9VytzMCW3tWHAXtKXmlURSc3ZdvwEcKCzw= github.com/libp2p/go-libp2p-transport-upgrader v0.1.1/go.mod h1:IEtA6or8JUbsV07qPW4r01GnTenLW4oi3lOPbUMGJJA= @@ -808,7 +785,6 @@ github.com/libp2p/go-maddr-filter v0.0.4/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9 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.1/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0= 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 h1:/nBTy5+1yRyY82YaO6HXQRnO5IAGsXTjEJaR3LdTPc0= @@ -819,7 +795,6 @@ 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 h1:Ov/D+8oBlbRkjBs1R1Iua8hJ8cUfbdiW8EOdZuxcgaI= github.com/libp2p/go-mplex v0.2.0/go.mod h1:0Oy/A9PQlwBytDRp4wSkFnzHYDKcpLot35JQ6msjvYQ= -github.com/libp2p/go-msgio v0.0.1/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= 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= @@ -850,7 +825,6 @@ github.com/libp2p/go-reuseport v0.0.1 h1:7PhkfH73VXfPJYKQ6JwS5I/eVcoyYi9IMNGc6FW github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA= github.com/libp2p/go-reuseport v0.0.2 h1:XSG94b1FJfGA01BUrT82imejHQyTxO4jEWqheyCXYvU= github.com/libp2p/go-reuseport v0.0.2/go.mod h1:SPD+5RwGC7rcnzngoYC86GjPzjSywuQyMVAheVBD9nQ= -github.com/libp2p/go-reuseport-transport v0.0.1/go.mod h1:YkbSDrvjUVDL6b8XqriyA20obEtsW9BLkuOUyQAOCbs= github.com/libp2p/go-reuseport-transport v0.0.2 h1:WglMwyXyBu61CMkjCCtnmqNqnjib0GIEjMiHTwR/KN4= 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= @@ -868,7 +842,6 @@ github.com/libp2p/go-stream-muxer-multistream v0.2.0 h1:714bRJ4Zy9mdhyTLJ+ZKiROm 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-tcp-transport v0.0.1/go.mod h1:mnjg0o0O5TmXUaUIanYPUqkW4+u6mK0en8rlpA6BBTs= 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 h1:yGlqURmqgNA2fvzjSgZNlHcsd/IulAnKM8Ncu+vlqnw= @@ -879,7 +852,6 @@ github.com/libp2p/go-tcp-transport v0.2.1 h1:ExZiVQV+h+qL16fzCWtd1HSzPsqWottJ8KX github.com/libp2p/go-tcp-transport v0.2.1/go.mod h1:zskiJ70MEfWz2MKxvFB/Pv+tPIB1PpPUrHIWQ8aFw7M= 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.1/go.mod h1:p3bKjDWHEgtuKKj+2OdPYs5dAPIjtpQGHF2tJfGz7Ww= 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.2.0 h1:MJCw2OrPA9+76YNRvdo1wMnSOxb9Bivj6sVFY1Xrj6w= @@ -933,7 +905,6 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5 github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4= 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.1.4/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.12 h1:WMhc1ik4LNkTg8U9l3hI1LvxKmIL+f1+WV/SZtCbDDA= github.com/miekg/dns v1.1.12/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.28 h1:gQhy5bsJa8zTlVI8lywCTZp1lguor+xevFoYlzeCTQY= @@ -950,6 +921,7 @@ github.com/minio/sha256-simd v0.1.1 h1:5QHSlgo3nt5yKOJrC7W8w7X+NFl8cMPZm96iu8kKU github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= 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/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= 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= @@ -1011,7 +983,6 @@ github.com/multiformats/go-multibase v0.0.3 h1:l/B6bJDQjvQ5G52jw4QGSYeOTZoAwIO77 github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc= 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.7/go.mod h1:XuKXPp8VHcTygube3OWZC+aZrA+H1IhmjoCDtJc7PXM= github.com/multiformats/go-multihash v0.0.8 h1:wrYcW5yxSi3dU07n5jnuS5PrNwyHy0zRHGVoUugWvXg= github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= github.com/multiformats/go-multihash v0.0.9 h1:aoijQXYYl7Xtb2pUUP68R+ys1TlnlR3eX6wmozr0Hp4= @@ -1205,10 +1176,6 @@ github.com/whyrusleeping/go-logging v0.0.1 h1:fwpzlmT0kRC/Fmd0MdmGgJG/CXIZ6gFq46 github.com/whyrusleeping/go-logging v0.0.1/go.mod h1:lDPYj54zutzG1XYfHAhcc7oNXEburHQBn+Iqd4yS4vE= github.com/whyrusleeping/go-notifier v0.0.0-20170827234753-097c5d47330f h1:M/lL30eFZTKnomXY6huvM6G0+gVquFNf6mxghaWlFUg= github.com/whyrusleeping/go-notifier v0.0.0-20170827234753-097c5d47330f/go.mod h1:cZNvX9cFybI01GriPRMXDtczuvUhgbcYr9iCGaNlRv8= -github.com/whyrusleeping/go-smux-multiplex v3.0.16+incompatible/go.mod h1:34LEDbeKFZInPUrAG+bjuJmUXONGdEFW7XL0SpTY1y4= -github.com/whyrusleeping/go-smux-multistream v2.0.2+incompatible/go.mod h1:dRWHHvc4HDQSHh9gbKEBbUZ+f2Q8iZTPG3UOGYODxSQ= -github.com/whyrusleeping/go-smux-yamux v2.0.8+incompatible/go.mod h1:6qHUzBXUbB9MXmw3AUdB52L8sEb/hScCqOdW2kj/wuI= -github.com/whyrusleeping/go-smux-yamux v2.0.9+incompatible/go.mod h1:6qHUzBXUbB9MXmw3AUdB52L8sEb/hScCqOdW2kj/wuI= github.com/whyrusleeping/go-sysinfo v0.0.0-20190219211824-4a357d4b90b1 h1:ctS9Anw/KozviCCtK6VWMz5kPL9nbQzbQY4yfqlIV4M= github.com/whyrusleeping/go-sysinfo v0.0.0-20190219211824-4a357d4b90b1/go.mod h1:tKH72zYNt/exx6/5IQO6L9LoQ0rEjd5SbbWaDTs9Zso= github.com/whyrusleeping/mafmt v1.2.8 h1:TCghSl5kkwEE0j+sU/gudyhVMRlpBin8fMBBHg59EbA= @@ -1222,7 +1189,6 @@ github.com/whyrusleeping/tar-utils v0.0.0-20201201191210-20a61371de5b h1:wA3QeTs github.com/whyrusleeping/tar-utils v0.0.0-20201201191210-20a61371de5b/go.mod h1:xT1Y5p2JR2PfSZihE0s4mjdJaRGp1waCTf5JzhQLBck= 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/whyrusleeping/yamux v1.1.5/go.mod h1:E8LnQQ8HKx5KD29HZFUwM1PxCOdPRzGwur1mcYhXcD8= github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -1332,7 +1298,6 @@ golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/net v0.0.0-20180524181706-dfa909b99c79/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= @@ -1372,6 +1337,7 @@ golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAG 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 h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 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= @@ -1503,6 +1469,7 @@ google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 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.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= 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= diff --git a/test/sharness/t0700-remotepin.sh b/test/sharness/t0700-remotepin.sh new file mode 100755 index 00000000000..a033f87457f --- /dev/null +++ b/test/sharness/t0700-remotepin.sh @@ -0,0 +1,271 @@ +#!/usr/bin/env bash + +test_description="Test ipfs remote pinning operations" + +. lib/test-lib.sh + +if [ -z ${DOCKER_HOST+x} ]; then + # TODO: set up instead of skipping? + skip_all='Skipping pinning service integration tests: missing DOCKER_HOST, remote pinning service not available' + test_done +fi + +# daemon running in online mode to ensure Pin.origins/PinStatus.delegates work +test_init_ipfs +test_launch_ipfs_daemon + +# create user on pinning service +TEST_PIN_SVC="http://${DOCKER_HOST}:5000/api/v1" +TEST_PIN_SVC_KEY=$(curl -s -X POST "$TEST_PIN_SVC/users" -d email="go-ipfs-sharness@ipfs.example.com" | jq --raw-output .access_token) + +# pin remote service add|ls|rm + +# add valid and invalid services +test_expect_success "creating test user on remote pinning service" ' + echo CI host IP address ${TEST_PIN_SVC} && + ipfs pin remote service add test_pin_svc ${TEST_PIN_SVC} ${TEST_PIN_SVC_KEY} && + ipfs pin remote service add test_invalid_key_svc ${TEST_PIN_SVC} fake_api_key && + ipfs pin remote service add test_invalid_url_path_svc ${TEST_PIN_SVC}/invalid-path fake_api_key && + ipfs pin remote service add test_invalid_url_dns_svc https://invalid-service.example.com fake_api_key +' + +test_expect_success "test 'ipfs pin remote service ls'" ' + ipfs pin remote service ls | tee ls_out && + grep -q test_pin_svc ls_out && + grep -q test_invalid_key_svc ls_out && + grep -q test_invalid_url_path_svc ls_out && + grep -q test_invalid_url_dns_svc ls_out +' + +# SECURITY of access tokens in Api.Key fields: +# Pinning.RemoteServices includes Api.Key, and we give it the same treatment +# as Identity.PrivKey to prevent exposing it on the network + +test_expect_success "'ipfs config Pinning' fails" ' + test_expect_code 1 ipfs config Pinning 2>&1 > config_out +' +test_expect_success "output does not include Api.Key" ' + test_expect_code 1 grep -q Key config_out +' + +test_expect_success "'ipfs config Pinning.RemoteServices.test_pin_svc.Api.Key' fails" ' + test_expect_code 1 ipfs config Pinning.RemoteServices.test_pin_svc.Api.Key 2> config_out +' + +test_expect_success "output includes meaningful error" ' + echo "Error: cannot show or change pinning services through this API (try: ipfs pin remote service --help)" > config_exp && + test_cmp config_exp config_out +' + +test_expect_success "'ipfs config Pinning.RemoteServices.test_pin_svc' fails" ' + test_expect_code 1 ipfs config Pinning.RemoteServices.test_pin_svc 2> config_out +' +test_expect_success "output includes meaningful error" ' + test_cmp config_exp config_out +' + +test_expect_success "'ipfs config show' doesn't include RemoteServices" ' + ipfs config show > show_config && + test_expect_code 1 grep RemoteServices show_config +' + +test_expect_success "'ipfs config replace' injects remote services back" ' + test_expect_code 1 grep -q -E "test_.+_svc" show_config && + ipfs config replace show_config && + test_expect_code 0 grep -q test_pin_svc "$IPFS_PATH/config" && + test_expect_code 0 grep -q test_invalid_key_svc "$IPFS_PATH/config" && + test_expect_code 0 grep -q test_invalid_url_path_svc "$IPFS_PATH/config" && + test_expect_code 0 grep -q test_invalid_url_dns_svc "$IPFS_PATH/config" +' + +# note: we remove Identity.PrivKey to ensure error is triggered by Pinning.RemoteServices +test_expect_success "'ipfs config replace' with remote services errors out" ' + jq -M "del(.Identity.PrivKey)" "$IPFS_PATH/config" | jq ".Pinning += { RemoteServices: {\"foo\": {} }}" > new_config && + test_expect_code 1 ipfs config replace - < new_config 2> replace_out +' +test_expect_success "output includes meaningful error" ' + echo "Error: cannot show or change pinning services through this API (try: ipfs pin remote service --help)" > replace_expected && + test_cmp replace_out replace_expected +' + +# /SECURITY + +test_expect_success "pin remote service ls --stat' returns numbers for a valid service" ' + ipfs pin remote service ls --stat | grep -E "^test_pin_svc.+[0-9]+/[0-9]+/[0-9]+/[0-9]+$" +' + +test_expect_success "pin remote service ls --enc=json --stat' returns valid status" " + ipfs pin remote service ls --stat --enc=json | jq --raw-output '.RemoteServices[] | select(.Service == \"test_pin_svc\") | .Stat.Status' | tee stat_out && + echo valid > stat_expected && + test_cmp stat_out stat_expected +" + +test_expect_success "pin remote service ls --stat' returns invalid status for invalid service" ' + ipfs pin remote service ls --stat | grep -E "^test_invalid_url_path_svc.+invalid$" +' + +test_expect_success "pin remote service ls --enc=json --stat' returns invalid status" " + ipfs pin remote service ls --stat --enc=json | jq --raw-output '.RemoteServices[] | select(.Service == \"test_invalid_url_path_svc\") | .Stat.Status' | tee stat_out && + echo invalid > stat_expected && + test_cmp stat_out stat_expected +" + +test_expect_success "pin remote service ls --enc=json' (without --stat) returns no Stat object" " + ipfs pin remote service ls --enc=json | jq --raw-output '.RemoteServices[] | select(.Service == \"test_invalid_url_path_svc\") | .Stat' | tee stat_out && + echo null > stat_expected && + test_cmp stat_out stat_expected +" + +test_expect_success "check connection to the test pinning service" ' + ipfs pin remote ls --service=test_pin_svc --enc=json +' + +test_expect_success "unauthorized pinning service calls fail" ' + test_expect_code 1 ipfs pin remote ls --service=test_invalid_key_svc +' + +test_expect_success "misconfigured pinning service calls fail (wrong path)" ' + test_expect_code 1 ipfs pin remote ls --service=test_invalid_url_path_svc +' + +test_expect_success "misconfigured pinning service calls fail (dns error)" ' + test_expect_code 1 ipfs pin remote ls --service=test_invalid_url_dns_svc +' + +# pin remote service rm + +test_expect_success "remove pinning service" ' + ipfs pin remote service rm test_invalid_key_svc && + ipfs pin remote service rm test_invalid_url_path_svc && + ipfs pin remote service rm test_invalid_url_dns_svc +' + +test_expect_success "verify pinning service removal works" ' + ipfs pin remote service ls | tee ls_out && + test_expect_code 1 grep test_invalid_key_svc ls_out && + test_expect_code 1 grep test_invalid_url_path_svc ls_out && + test_expect_code 1 grep test_invalid_url_dns_svc ls_out +' + +# pin remote add + +# we leverage the fact that inlined CID can be pinned instantly on the remote service +# (https://github.com/ipfs-shipyard/rb-pinning-service-api/issues/8) +# below test ensures that assumption is correct (before we proceed to actual tests) +test_expect_success "verify that default add (implicit --background=false) works with data inlined in CID" ' + ipfs pin remote add --service=test_pin_svc --name=inlined_null bafkqaaa && + ipfs pin remote ls --service=test_pin_svc --enc=json --name=inlined_null --status=pinned | jq --raw-output .Status | tee ls_out && + grep -q "pinned" ls_out +' + +test_remote_pins() { + BASE=$1 + if [ -n "$BASE" ]; then + BASE_ARGS="--cid-base=$BASE" + fi + + # note: HAS_MISSING is not inlined nor imported to IPFS on purpose, to reliably test 'queued' state + test_expect_success "create some hashes using base $BASE" ' + export HASH_A=$(echo -n "A @ $(date +%s.%N)" | ipfs add $BASE_ARGS -q --inline --inline-limit 1000 --pin=false) && + export HASH_B=$(echo -n "B @ $(date +%s.%N)" | ipfs add $BASE_ARGS -q --inline --inline-limit 1000 --pin=false) && + export HASH_C=$(echo -n "C @ $(date +%s.%N)" | ipfs add $BASE_ARGS -q --inline --inline-limit 1000 --pin=false) && + export HASH_MISSING=$(echo "MISSING FROM IPFS @ $(date +%s.%N)" | ipfs add $BASE_ARGS -q --only-hash) && + echo "A: $HASH_A" && + echo "B: $HASH_B" && + echo "C: $HASH_C" && + echo "M: $HASH_MISSING" + ' + + test_expect_success "'ipfs pin remote add --background=true'" ' + ipfs pin remote add --background=true --service=test_pin_svc --enc=json $BASE_ARGS --name=name_a $HASH_A + ' + + test_expect_success "verify background add worked (instantly pinned variant)" ' + ipfs pin remote ls --service=test_pin_svc --enc=json --name=name_a | tee ls_out && + test_expect_code 0 grep -q name_a ls_out && + test_expect_code 0 grep -q $HASH_A ls_out + ' + + test_expect_success "'ipfs pin remote add --background=true' with CID that is not available" ' + test_expect_code 0 ipfs pin remote add --background=true --service=test_pin_svc --enc=json $BASE_ARGS --name=name_m $HASH_MISSING + ' + + test_expect_success "verify background add worked (queued variant)" ' + ipfs pin remote ls --service=test_pin_svc --enc=json --name=name_m --status=queued,pinning | tee ls_out && + test_expect_code 0 grep -q name_m ls_out && + test_expect_code 0 grep -q $HASH_MISSING ls_out + ' + + test_expect_success "'ipfs pin remote add --background=false'" ' + test_expect_code 0 ipfs pin remote add --background=false --service=test_pin_svc --enc=json $BASE_ARGS --name=name_b $HASH_B + ' + + test_expect_success "verify foreground add worked" ' + ipfs pin remote ls --service=test_pin_svc --enc=json $ID_B | tee ls_out && + test_expect_code 0 grep -q name_b ls_out && + test_expect_code 0 grep -q pinned ls_out && + test_expect_code 0 grep -q $HASH_B ls_out + ' + + test_expect_success "'ipfs pin remote ls' for existing pins by multiple statuses" ' + ipfs pin remote ls --service=test_pin_svc --enc=json --status=queued,pinning,pinned,failed | tee ls_out && + test_expect_code 0 grep -q $HASH_A ls_out && + test_expect_code 0 grep -q $HASH_B ls_out && + test_expect_code 0 grep -q $HASH_MISSING ls_out + ' + + test_expect_success "'ipfs pin remote ls' for existing pins by CID" ' + ipfs pin remote ls --service=test_pin_svc --enc=json --cid=$HASH_B | tee ls_out && + test_expect_code 0 grep -q $HASH_B ls_out + ' + + test_expect_success "'ipfs pin remote ls' for existing pins by name" ' + ipfs pin remote ls --service=test_pin_svc --enc=json --name=name_a | tee ls_out && + test_expect_code 0 grep -q $HASH_A ls_out + ' + + test_expect_success "'ipfs pin remote ls' for ongoing pins by status" ' + ipfs pin remote ls --service=test_pin_svc --status=queued,pinning | tee ls_out && + test_expect_code 0 grep -q $HASH_MISSING ls_out + ' + + # --force is required only when more than a single match is found, + # so we add second pin with the same name (but different CID) to simulate that scenario + test_expect_success "'ipfs pin remote rm --name' fails without --force when matching multiple pins" ' + test_expect_code 0 ipfs pin remote add --service=test_pin_svc --enc=json $BASE_ARGS --name=name_b $HASH_C && + test_expect_code 1 ipfs pin remote rm --service=test_pin_svc --name=name_b 2> rm_out && + echo "Error: multiple remote pins are matching this query, add --force to confirm the bulk removal" > rm_expected && + test_cmp rm_out rm_expected + ' + + test_expect_success "'ipfs pin remote rm --name' without --force did not remove matching pins" ' + ipfs pin remote ls --service=test_pin_svc --enc=json --name=name_b | jq --raw-output .Cid | tee ls_out && + test_expect_code 0 grep -q $HASH_B ls_out && + test_expect_code 0 grep -q $HASH_C ls_out + ' + + test_expect_success "'ipfs pin remote rm --name' with --force removes all matching pins" ' + test_expect_code 0 ipfs pin remote rm --service=test_pin_svc --name=name_b --force && + ipfs pin remote ls --service=test_pin_svc --enc=json --name=name_b | jq --raw-output .Cid | tee ls_out && + test_expect_code 1 grep -q $HASH_B ls_out && + test_expect_code 1 grep -q $HASH_C ls_out + ' + + test_expect_success "'ipfs pin remote rm --force' removes all pinned items" ' + ipfs pin remote ls --service=test_pin_svc --enc=json --status=queued,pinning,pinned,failed | jq --raw-output .Cid | tee ls_out && + test_expect_code 0 grep -q $HASH_A ls_out && + test_expect_code 0 grep -q $HASH_MISSING ls_out && + ipfs pin remote rm --service=test_pin_svc --status=queued,pinning,pinned,failed --force && + ipfs pin remote ls --service=test_pin_svc --enc=json --status=queued,pinning,pinned,failed | jq --raw-output .Cid | tee ls_out && + test_expect_code 1 grep -q $HASH_A ls_out && + test_expect_code 1 grep -q $HASH_MISSING ls_out + ' + +} + +test_remote_pins "" + +test_kill_ipfs_daemon +test_done + +# vim: ts=2 sw=2 sts=2 et: From 246ec027b60b057b0a94605ff633d6ad83f61de9 Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Tue, 8 Dec 2020 20:40:29 -0500 Subject: [PATCH 064/116] chore: update dht --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 208ec025780..a626f74ab07 100644 --- a/go.mod +++ b/go.mod @@ -66,7 +66,7 @@ require ( github.com/libp2p/go-libp2p-core v0.7.0 github.com/libp2p/go-libp2p-discovery v0.5.0 github.com/libp2p/go-libp2p-http v0.2.0 - github.com/libp2p/go-libp2p-kad-dht v0.11.0 + github.com/libp2p/go-libp2p-kad-dht v0.11.1 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.3.0 diff --git a/go.sum b/go.sum index 03a445461ce..e56b78a5023 100644 --- a/go.sum +++ b/go.sum @@ -652,8 +652,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.0 h1:ZLhlmDKsFiOkPhTzfEqBrMy/1Tqx+Dk6UgbHM5//IQM= -github.com/libp2p/go-libp2p-kad-dht v0.11.0/go.mod h1:5ojtR2acDPqh/jXf5orWy8YGb8bHQDS+qeDcoscL/PI= +github.com/libp2p/go-libp2p-kad-dht v0.11.1 h1:FsriVQhOUZpCotWIjyFSjEDNJmUzuMma/RyyTDZanwc= +github.com/libp2p/go-libp2p-kad-dht v0.11.1/go.mod h1:5ojtR2acDPqh/jXf5orWy8YGb8bHQDS+qeDcoscL/PI= 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= github.com/libp2p/go-libp2p-loggables v0.0.1/go.mod h1:lDipDlBNYbpyqyPX/KcoO+eq0sJYEVR2JgOexcivchg= From fb3316ad05c0497fa2d5ba752e0efdebf40ac054 Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Tue, 8 Dec 2020 21:46:49 -0500 Subject: [PATCH 065/116] fix: decrease log level of opencensus initialization --- core/corehttp/metrics.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/corehttp/metrics.go b/core/corehttp/metrics.go index de0dcd7438f..8a73111fc91 100644 --- a/core/corehttp/metrics.go +++ b/core/corehttp/metrics.go @@ -26,7 +26,7 @@ func MetricsScrapingOption(path string) ServeOption { // This adds collection of OpenCensus metrics func MetricsOpenCensusCollectionOption() ServeOption { return func(_ *core.IpfsNode, _ net.Listener, mux *http.ServeMux) (*http.ServeMux, error) { - log.Error("Init OpenCensus") + log.Info("Init OpenCensus") promRegistry := prometheus.NewRegistry() pe, err := ocprom.NewExporter(ocprom.Options{ From 2ab79fa65b0224f965093defcb12648fb5d1f708 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 9 Dec 2020 11:27:16 +0000 Subject: [PATCH 066/116] chore(deps): bump go.opencensus.io from 0.22.4 to 0.22.5 Bumps [go.opencensus.io](https://github.com/census-instrumentation/opencensus-go) from 0.22.4 to 0.22.5. - [Release notes](https://github.com/census-instrumentation/opencensus-go/releases) - [Commits](https://github.com/census-instrumentation/opencensus-go/compare/v0.22.4...v0.22.5) Signed-off-by: dependabot-preview[bot] --- go.mod | 2 +- go.sum | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index bb8940270d8..8e3c05f59be 100644 --- a/go.mod +++ b/go.mod @@ -102,7 +102,7 @@ require ( github.com/whyrusleeping/go-sysinfo v0.0.0-20190219211824-4a357d4b90b1 github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 github.com/whyrusleeping/tar-utils v0.0.0-20201201191210-20a61371de5b - go.opencensus.io v0.22.4 + go.opencensus.io v0.22.5 go.uber.org/fx v1.13.1 go.uber.org/zap v1.16.0 golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a diff --git a/go.sum b/go.sum index f1d3eb8f58f..9e835c14042 100644 --- a/go.sum +++ b/go.sum @@ -1217,6 +1217,8 @@ 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 h1:LYy1Hy3MJdrCdMwwzxA/dRok4ejH+RwNGbuoD9fCjto= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5 h1:dntmOdLpSpHlVqbW5Eay97DelsZHe+55D+xC6i0dDS0= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0 h1:OI5t8sDa1Or+q8AeE+yKeB/SDYioSHAgcVljj9JIETY= @@ -1417,6 +1419,8 @@ 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 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 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= From 02d15ac4146988baf9cd1e8f2ce432f25fb06776 Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Wed, 9 Dec 2020 10:20:12 -0500 Subject: [PATCH 067/116] Release v0.8.0-rc1 --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index 5467c506032..6e2116f6b6e 100644 --- a/version.go +++ b/version.go @@ -4,7 +4,7 @@ package ipfs var CurrentCommit string // CurrentVersionNumber is the current application's version literal -const CurrentVersionNumber = "0.8.0-dev" +const CurrentVersionNumber = "0.8.0-rc1" const ApiVersion = "/go-ipfs/" + CurrentVersionNumber + "/" From 6af614615677f2ee22d5b6163402f3ee70c52579 Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Wed, 9 Dec 2020 13:17:28 -0500 Subject: [PATCH 068/116] update version to 0.9.0-dev --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index 5467c506032..52e4c6daf3b 100644 --- a/version.go +++ b/version.go @@ -4,7 +4,7 @@ package ipfs var CurrentCommit string // CurrentVersionNumber is the current application's version literal -const CurrentVersionNumber = "0.8.0-dev" +const CurrentVersionNumber = "0.9.0-dev" const ApiVersion = "/go-ipfs/" + CurrentVersionNumber + "/" From 9a33b04db41abdebc30e8f122a8b9034029a5910 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Thu, 10 Dec 2020 09:14:08 +0100 Subject: [PATCH 069/116] Update RELEASE_ISSUE_TEMPLATE.md --- docs/RELEASE_ISSUE_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/RELEASE_ISSUE_TEMPLATE.md b/docs/RELEASE_ISSUE_TEMPLATE.md index b6ad1fc1b6d..3f1c7ef35a9 100644 --- a/docs/RELEASE_ISSUE_TEMPLATE.md +++ b/docs/RELEASE_ISSUE_TEMPLATE.md @@ -60,7 +60,7 @@ Checklist: - [ ] Deploy new version to a subset of Preload nodes - [ ] Collect metrics every day. Work with the Infrastructure team to learn of any hiccup - [ ] IPFS Application Testing - Run the tests of the following applications: - - [ ] [IPFS Desktop](https://github.com/ipfs-shipyard/ipfs-desktop) - @hacdias + - [ ] [IPFS Desktop](https://github.com/ipfs-shipyard/ipfs-desktop) - @lidel - [ ] [IPFS Companion](https://github.com/ipfs-shipyard/ipfs-companion) - @lidel - [ ] [NPM on IPFS](https://github.com/ipfs-shipyard/npm-on-ipfs) - @achingbrain - [ ] **Stage 2 - Community Dev Testing** From 4d52bbdde8dce668901d771ee86662f7272cdb19 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Tue, 15 Dec 2020 00:42:18 +0100 Subject: [PATCH 070/116] fix: remote services ls always return a list Closes #7824 --- core/commands/pin/remotepin.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/commands/pin/remotepin.go b/core/commands/pin/remotepin.go index 12a2639c998..7257d451884 100644 --- a/core/commands/pin/remotepin.go +++ b/core/commands/pin/remotepin.go @@ -486,7 +486,7 @@ var lsRemotePinServiceCmd = &cmds.Command{ return err } if cfg.Pinning.RemoteServices == nil { - return nil // no pinning services added yet + return cmds.EmitOnce(res, &PinServicesList{make([]ServiceDetails, 0)}) } services := cfg.Pinning.RemoteServices result := PinServicesList{make([]ServiceDetails, 0, len(services))} From 7193f950d795bb87c075edf1d9e41e7c131d7d8b Mon Sep 17 00:00:00 2001 From: gammazero Date: Thu, 17 Dec 2020 17:08:48 -0800 Subject: [PATCH 071/116] Escape non-printable characters in user output Replaces control characters and non-printable characters with escape sequences, in any fields that are printed by the CLI, which could have been user input. Output from `ipfs cat` is unchanged. --- core/commands/add.go | 2 +- core/commands/cmdenv/env.go | 12 ++++++++++++ core/commands/dns.go | 3 ++- core/commands/keystore.go | 8 ++++---- core/commands/ls.go | 2 +- core/commands/mount_unix.go | 4 ++-- core/commands/name/publish.go | 4 ++-- core/commands/object/object.go | 2 +- core/commands/pin/remotepin.go | 2 +- core/commands/pubsub.go | 2 +- core/commands/unixfs/ls.go | 4 ++-- 11 files changed, 29 insertions(+), 16 deletions(-) diff --git a/core/commands/add.go b/core/commands/add.go index 1c4c8603004..ba0dc2ecbd5 100644 --- a/core/commands/add.go +++ b/core/commands/add.go @@ -353,7 +353,7 @@ only-hash, and progress/status related flags) will change the final hash. if quiet { fmt.Fprintf(os.Stdout, "%s\n", output.Hash) } else { - fmt.Fprintf(os.Stdout, "added %s %s\n", output.Hash, output.Name) + fmt.Fprintf(os.Stdout, "added %s %s\n", output.Hash, cmdenv.EscNonPrint(output.Name)) } } else { diff --git a/core/commands/cmdenv/env.go b/core/commands/cmdenv/env.go index 82df803acf8..7e847525c42 100644 --- a/core/commands/cmdenv/env.go +++ b/core/commands/cmdenv/env.go @@ -2,6 +2,7 @@ package cmdenv import ( "fmt" + "strconv" "strings" "github.com/ipfs/go-ipfs/commands" @@ -70,3 +71,14 @@ func GetConfigRoot(env cmds.Environment) (string, error) { return ctx.ConfigRoot, nil } + +// EscNonPrint converts control characters and non-printable characters into Go +// escape sequences, if the given string contains any. +func EscNonPrint(s string) string { + for _, r := range s { + if !strconv.IsPrint(r) { + return strings.Trim(strconv.Quote(s), "\"") + } + } + return s +} diff --git a/core/commands/dns.go b/core/commands/dns.go index a775f09db1f..d5dea4cf1d6 100644 --- a/core/commands/dns.go +++ b/core/commands/dns.go @@ -4,6 +4,7 @@ import ( "fmt" "io" + cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv" ncmd "github.com/ipfs/go-ipfs/core/commands/name" namesys "github.com/ipfs/go-ipfs/namesys" nsopts "github.com/ipfs/interface-go-ipfs-core/options/namesys" @@ -77,7 +78,7 @@ The resolver can recursively resolve: }, Encoders: cmds.EncoderMap{ cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *ncmd.ResolvedPath) error { - fmt.Fprintln(w, out.Path.String()) + fmt.Fprintln(w, cmdenv.EscNonPrint(out.Path.String())) return nil }), }, diff --git a/core/commands/keystore.go b/core/commands/keystore.go index 0e242ee96a4..5f2388ddeae 100644 --- a/core/commands/keystore.go +++ b/core/commands/keystore.go @@ -383,9 +383,9 @@ var keyRenameCmd = &cmds.Command{ Encoders: cmds.EncoderMap{ cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, kro *KeyRenameOutput) error { if kro.Overwrite { - fmt.Fprintf(w, "Key %s renamed to %s with overwriting\n", kro.Id, kro.Now) + fmt.Fprintf(w, "Key %s renamed to %s with overwriting\n", kro.Id, cmdenv.EscNonPrint(kro.Now)) } else { - fmt.Fprintf(w, "Key %s renamed to %s\n", kro.Id, kro.Now) + fmt.Fprintf(w, "Key %s renamed to %s\n", kro.Id, cmdenv.EscNonPrint(kro.Now)) } return nil }), @@ -547,9 +547,9 @@ func keyOutputListEncoders() cmds.EncoderFunc { tw := tabwriter.NewWriter(w, 1, 2, 1, ' ', 0) for _, s := range list.Keys { if withID { - fmt.Fprintf(tw, "%s\t%s\t\n", s.Id, s.Name) + fmt.Fprintf(tw, "%s\t%s\t\n", s.Id, cmdenv.EscNonPrint(s.Name)) } else { - fmt.Fprintf(tw, "%s\n", s.Name) + fmt.Fprintf(tw, "%s\n", cmdenv.EscNonPrint(s.Name)) } } tw.Flush() diff --git a/core/commands/ls.go b/core/commands/ls.go index 4b0114d3341..1a7b0c3fc17 100644 --- a/core/commands/ls.go +++ b/core/commands/ls.go @@ -251,7 +251,7 @@ func tabularOutput(req *cmds.Request, w io.Writer, out *LsOutput, lastObjectHash } } - fmt.Fprintf(tw, s, link.Hash, link.Size, link.Name) + fmt.Fprintf(tw, s, link.Hash, link.Size, cmdenv.EscNonPrint(link.Name)) } } tw.Flush() diff --git a/core/commands/mount_unix.go b/core/commands/mount_unix.go index 1a7e0118bfc..c6678d17585 100644 --- a/core/commands/mount_unix.go +++ b/core/commands/mount_unix.go @@ -119,8 +119,8 @@ baz Type: config.Mounts{}, Encoders: cmds.EncoderMap{ cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, mounts *config.Mounts) error { - fmt.Fprintf(w, "IPFS mounted at: %s\n", mounts.IPFS) - fmt.Fprintf(w, "IPNS mounted at: %s\n", mounts.IPNS) + fmt.Fprintf(w, "IPFS mounted at: %s\n", cmdenv.EscNonPrint(mounts.IPFS)) + fmt.Fprintf(w, "IPNS mounted at: %s\n", cmdenv.EscNonPrint(mounts.IPNS)) return nil }), diff --git a/core/commands/name/publish.go b/core/commands/name/publish.go index 99f0ab3cd2b..abf1ce34e5b 100644 --- a/core/commands/name/publish.go +++ b/core/commands/name/publish.go @@ -152,9 +152,9 @@ Alternatively, publish an using a valid PeerID (as listed by var err error quieter, _ := req.Options[quieterOptionName].(bool) if quieter { - _, err = fmt.Fprintln(w, ie.Name) + _, err = fmt.Fprintln(w, cmdenv.EscNonPrint(ie.Name)) } else { - _, err = fmt.Fprintf(w, "Published to %s: %s\n", ie.Name, ie.Value) + _, err = fmt.Fprintf(w, "Published to %s: %s\n", cmdenv.EscNonPrint(ie.Name), ie.Value) } return err }), diff --git a/core/commands/object/object.go b/core/commands/object/object.go index b5858546f75..ed5bbcf24d7 100644 --- a/core/commands/object/object.go +++ b/core/commands/object/object.go @@ -167,7 +167,7 @@ multihash. fmt.Fprintln(tw, "Hash\tSize\tName") } for _, link := range out.Links { - fmt.Fprintf(tw, "%s\t%v\t%s\n", link.Hash, link.Size, link.Name) + fmt.Fprintf(tw, "%s\t%v\t%s\n", link.Hash, link.Size, cmdenv.EscNonPrint(link.Name)) } tw.Flush() diff --git a/core/commands/pin/remotepin.go b/core/commands/pin/remotepin.go index 12a2639c998..3bd71bb3dec 100644 --- a/core/commands/pin/remotepin.go +++ b/core/commands/pin/remotepin.go @@ -254,7 +254,7 @@ Returns a list of objects that are pinned to a remote pinning service. Encoders: cmds.EncoderMap{ cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *RemotePinOutput) error { // pin remote ls produces a flat output similar to legacy pin ls - fmt.Fprintf(w, "%s\t%s\t%s\n", out.Cid, out.Status, out.Name) + fmt.Fprintf(w, "%s\t%s\t%s\n", out.Cid, out.Status, cmdenv.EscNonPrint(out.Name)) return nil }), }, diff --git a/core/commands/pubsub.go b/core/commands/pubsub.go index 10bddcd57be..1ec5016d6fd 100644 --- a/core/commands/pubsub.go +++ b/core/commands/pubsub.go @@ -205,7 +205,7 @@ To use, the daemon must be run with '--enable-pubsub-experiment'. func stringListEncoder(req *cmds.Request, w io.Writer, list *stringList) error { for _, str := range list.Strings { - _, err := fmt.Fprintf(w, "%s\n", str) + _, err := fmt.Fprintf(w, "%s\n", cmdenv.EscNonPrint(str)) if err != nil { return err } diff --git a/core/commands/unixfs/ls.go b/core/commands/unixfs/ls.go index fee64c713fd..e5fd4e0c260 100644 --- a/core/commands/unixfs/ls.go +++ b/core/commands/unixfs/ls.go @@ -213,12 +213,12 @@ If possible, please use 'ipfs ls' instead. if len(out.Arguments) > 1 { for _, arg := range directories[i:] { if out.Arguments[arg] == hash { - fmt.Fprintf(tw, "%s:\n", arg) + fmt.Fprintf(tw, "%s:\n", cmdenv.EscNonPrint(arg)) } } } for _, link := range object.Links { - fmt.Fprintf(tw, "%s\n", link.Name) + fmt.Fprintf(tw, "%s\n", cmdenv.EscNonPrint(link.Name)) } } tw.Flush() From e777adf04d54ad61e154b2c0b2d8933466a03888 Mon Sep 17 00:00:00 2001 From: gammazero Date: Thu, 17 Dec 2020 19:32:03 -0800 Subject: [PATCH 072/116] Test ls and add with escaped character --- test/sharness/t0045-ls.sh | 68 ++++++++++++++++++++++----------------- 1 file changed, 39 insertions(+), 29 deletions(-) diff --git a/test/sharness/t0045-ls.sh b/test/sharness/t0045-ls.sh index 890292b8e39..a090b0ac657 100755 --- a/test/sharness/t0045-ls.sh +++ b/test/sharness/t0045-ls.sh @@ -19,6 +19,7 @@ test_ls_cmd() { random 128 42 >testData/d1/128 && echo "world" >testData/d2/a && random 1024 42 >testData/d2/1024 && + echo "badname" >testData/d2/`echo -e "bad\x7fname.txt"` && ipfs add -r testData >actual_add ' @@ -28,30 +29,32 @@ added QmQNd6ubRXaNG6Prov8o6vk3bn6eWsj9FxLGrAVDUAGkGe testData/d1/128 added QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN testData/d1/a added QmbQBUSRL9raZtNXfpTDeaxQapibJEG6qEY8WqAN22aUzd testData/d2/1024 added QmaRGe7bVmVaLmxbrMiVNXqW4pRNNp3xq7hFtyRKA3mtJL testData/d2/a +added QmQSLRRd1Lxn6NMsWmmj2g9W3LtSRfmVAVqU3ShneLUrbn testData/d2/bad\u007fname.txt added QmeomffUNfmQy76CQGy9NdmqEnnHU9soCexBnGU3ezPHVH testData/f1 added QmNtocSs7MoDkJMc1RkyisCSKvLadujPsfJfSdJ3e1eA1M testData/f2 added QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss testData/d1 -added QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy testData/d2 -added QmfNy183bXiRVyrhyWtq3TwHn79yHEkiAGFr18P7YNzESj testData +added Qmf9nCpkCfa8Gtz5m1NJMeHBWcBozKRcbdom338LukPAjy testData/d2 +added QmRPX2PWaPGqzoVzqNcQkueijHVzPicjupnD7eLck6Rs21 testData EOF test_cmp expected_add actual_add ' test_expect_success "'ipfs ls ' succeeds" ' - ipfs ls QmfNy183bXiRVyrhyWtq3TwHn79yHEkiAGFr18P7YNzESj QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss >actual_ls + ipfs ls QmRPX2PWaPGqzoVzqNcQkueijHVzPicjupnD7eLck6Rs21 Qmf9nCpkCfa8Gtz5m1NJMeHBWcBozKRcbdom338LukPAjy QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss >actual_ls ' test_expect_success "'ipfs ls ' output looks good" ' cat <<-\EOF >expected_ls && -QmfNy183bXiRVyrhyWtq3TwHn79yHEkiAGFr18P7YNzESj: +QmRPX2PWaPGqzoVzqNcQkueijHVzPicjupnD7eLck6Rs21: QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss - d1/ -QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy - d2/ +Qmf9nCpkCfa8Gtz5m1NJMeHBWcBozKRcbdom338LukPAjy - d2/ QmeomffUNfmQy76CQGy9NdmqEnnHU9soCexBnGU3ezPHVH 5 f1 QmNtocSs7MoDkJMc1RkyisCSKvLadujPsfJfSdJ3e1eA1M 5 f2 -QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy: +Qmf9nCpkCfa8Gtz5m1NJMeHBWcBozKRcbdom338LukPAjy: QmbQBUSRL9raZtNXfpTDeaxQapibJEG6qEY8WqAN22aUzd 1024 1024 QmaRGe7bVmVaLmxbrMiVNXqW4pRNNp3xq7hFtyRKA3mtJL 6 a +QmQSLRRd1Lxn6NMsWmmj2g9W3LtSRfmVAVqU3ShneLUrbn 8 bad\u007fname.txt QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss: QmQNd6ubRXaNG6Prov8o6vk3bn6eWsj9FxLGrAVDUAGkGe 128 128 @@ -61,20 +64,21 @@ EOF ' test_expect_success "'ipfs ls --size=false ' succeeds" ' - ipfs ls --size=false QmfNy183bXiRVyrhyWtq3TwHn79yHEkiAGFr18P7YNzESj QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss >actual_ls + ipfs ls --size=false QmRPX2PWaPGqzoVzqNcQkueijHVzPicjupnD7eLck6Rs21 Qmf9nCpkCfa8Gtz5m1NJMeHBWcBozKRcbdom338LukPAjy QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss >actual_ls ' test_expect_success "'ipfs ls ' output looks good" ' cat <<-\EOF >expected_ls && -QmfNy183bXiRVyrhyWtq3TwHn79yHEkiAGFr18P7YNzESj: +QmRPX2PWaPGqzoVzqNcQkueijHVzPicjupnD7eLck6Rs21: QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss d1/ -QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy d2/ +Qmf9nCpkCfa8Gtz5m1NJMeHBWcBozKRcbdom338LukPAjy d2/ QmeomffUNfmQy76CQGy9NdmqEnnHU9soCexBnGU3ezPHVH f1 QmNtocSs7MoDkJMc1RkyisCSKvLadujPsfJfSdJ3e1eA1M f2 -QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy: +Qmf9nCpkCfa8Gtz5m1NJMeHBWcBozKRcbdom338LukPAjy: QmbQBUSRL9raZtNXfpTDeaxQapibJEG6qEY8WqAN22aUzd 1024 QmaRGe7bVmVaLmxbrMiVNXqW4pRNNp3xq7hFtyRKA3mtJL a +QmQSLRRd1Lxn6NMsWmmj2g9W3LtSRfmVAVqU3ShneLUrbn bad\u007fname.txt QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss: QmQNd6ubRXaNG6Prov8o6vk3bn6eWsj9FxLGrAVDUAGkGe 128 @@ -84,22 +88,23 @@ EOF ' test_expect_success "'ipfs ls --headers ' succeeds" ' - ipfs ls --headers QmfNy183bXiRVyrhyWtq3TwHn79yHEkiAGFr18P7YNzESj QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss >actual_ls_headers + ipfs ls --headers QmRPX2PWaPGqzoVzqNcQkueijHVzPicjupnD7eLck6Rs21 Qmf9nCpkCfa8Gtz5m1NJMeHBWcBozKRcbdom338LukPAjy QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss >actual_ls_headers ' test_expect_success "'ipfs ls --headers ' output looks good" ' cat <<-\EOF >expected_ls_headers && -QmfNy183bXiRVyrhyWtq3TwHn79yHEkiAGFr18P7YNzESj: +QmRPX2PWaPGqzoVzqNcQkueijHVzPicjupnD7eLck6Rs21: Hash Size Name QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss - d1/ -QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy - d2/ +Qmf9nCpkCfa8Gtz5m1NJMeHBWcBozKRcbdom338LukPAjy - d2/ QmeomffUNfmQy76CQGy9NdmqEnnHU9soCexBnGU3ezPHVH 5 f1 QmNtocSs7MoDkJMc1RkyisCSKvLadujPsfJfSdJ3e1eA1M 5 f2 -QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy: +Qmf9nCpkCfa8Gtz5m1NJMeHBWcBozKRcbdom338LukPAjy: Hash Size Name QmbQBUSRL9raZtNXfpTDeaxQapibJEG6qEY8WqAN22aUzd 1024 1024 QmaRGe7bVmVaLmxbrMiVNXqW4pRNNp3xq7hFtyRKA3mtJL 6 a +QmQSLRRd1Lxn6NMsWmmj2g9W3LtSRfmVAVqU3ShneLUrbn 8 bad\u007fname.txt QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss: Hash Size Name @@ -110,7 +115,7 @@ EOF ' test_expect_success "'ipfs ls --size=false --cid-base=base32 ' succeeds" ' - ipfs ls --size=false --cid-base=base32 $(cid-fmt -v 1 -b base32 %s QmfNy183bXiRVyrhyWtq3TwHn79yHEkiAGFr18P7YNzESj QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss) >actual_ls_base32 + ipfs ls --size=false --cid-base=base32 $(cid-fmt -v 1 -b base32 %s QmRPX2PWaPGqzoVzqNcQkueijHVzPicjupnD7eLck6Rs21 Qmf9nCpkCfa8Gtz5m1NJMeHBWcBozKRcbdom338LukPAjy QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss) >actual_ls_base32 ' test_expect_success "'ipfs ls --size=false --cid-base=base32 ' output looks good" ' @@ -130,6 +135,7 @@ test_ls_cmd_streaming() { random 128 42 >testData/d1/128 && echo "world" >testData/d2/a && random 1024 42 >testData/d2/1024 && + echo "badname" >testData/d2/`echo -e "bad\x7fname.txt"` && ipfs add -r testData >actual_add ' @@ -139,30 +145,32 @@ added QmQNd6ubRXaNG6Prov8o6vk3bn6eWsj9FxLGrAVDUAGkGe testData/d1/128 added QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN testData/d1/a added QmbQBUSRL9raZtNXfpTDeaxQapibJEG6qEY8WqAN22aUzd testData/d2/1024 added QmaRGe7bVmVaLmxbrMiVNXqW4pRNNp3xq7hFtyRKA3mtJL testData/d2/a +added QmQSLRRd1Lxn6NMsWmmj2g9W3LtSRfmVAVqU3ShneLUrbn testData/d2/bad\u007fname.txt added QmeomffUNfmQy76CQGy9NdmqEnnHU9soCexBnGU3ezPHVH testData/f1 added QmNtocSs7MoDkJMc1RkyisCSKvLadujPsfJfSdJ3e1eA1M testData/f2 added QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss testData/d1 -added QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy testData/d2 -added QmfNy183bXiRVyrhyWtq3TwHn79yHEkiAGFr18P7YNzESj testData +added Qmf9nCpkCfa8Gtz5m1NJMeHBWcBozKRcbdom338LukPAjy testData/d2 +added QmRPX2PWaPGqzoVzqNcQkueijHVzPicjupnD7eLck6Rs21 testData EOF test_cmp expected_add actual_add ' test_expect_success "'ipfs ls --stream ' succeeds" ' - ipfs ls --stream QmfNy183bXiRVyrhyWtq3TwHn79yHEkiAGFr18P7YNzESj QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss >actual_ls_stream + ipfs ls --stream QmRPX2PWaPGqzoVzqNcQkueijHVzPicjupnD7eLck6Rs21 Qmf9nCpkCfa8Gtz5m1NJMeHBWcBozKRcbdom338LukPAjy QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss >actual_ls_stream ' test_expect_success "'ipfs ls --stream ' output looks good" ' cat <<-\EOF >expected_ls_stream && -QmfNy183bXiRVyrhyWtq3TwHn79yHEkiAGFr18P7YNzESj: +QmRPX2PWaPGqzoVzqNcQkueijHVzPicjupnD7eLck6Rs21: QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss - d1/ -QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy - d2/ +Qmf9nCpkCfa8Gtz5m1NJMeHBWcBozKRcbdom338LukPAjy - d2/ QmeomffUNfmQy76CQGy9NdmqEnnHU9soCexBnGU3ezPHVH 5 f1 QmNtocSs7MoDkJMc1RkyisCSKvLadujPsfJfSdJ3e1eA1M 5 f2 -QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy: +Qmf9nCpkCfa8Gtz5m1NJMeHBWcBozKRcbdom338LukPAjy: QmbQBUSRL9raZtNXfpTDeaxQapibJEG6qEY8WqAN22aUzd 1024 1024 QmaRGe7bVmVaLmxbrMiVNXqW4pRNNp3xq7hFtyRKA3mtJL 6 a +QmQSLRRd1Lxn6NMsWmmj2g9W3LtSRfmVAVqU3ShneLUrbn 8 bad\u007fname.txt QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss: QmQNd6ubRXaNG6Prov8o6vk3bn6eWsj9FxLGrAVDUAGkGe 128 128 @@ -172,20 +180,21 @@ EOF ' test_expect_success "'ipfs ls --size=false --stream ' succeeds" ' - ipfs ls --size=false --stream QmfNy183bXiRVyrhyWtq3TwHn79yHEkiAGFr18P7YNzESj QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss >actual_ls_stream + ipfs ls --size=false --stream QmRPX2PWaPGqzoVzqNcQkueijHVzPicjupnD7eLck6Rs21 Qmf9nCpkCfa8Gtz5m1NJMeHBWcBozKRcbdom338LukPAjy QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss >actual_ls_stream ' test_expect_success "'ipfs ls --size=false --stream ' output looks good" ' cat <<-\EOF >expected_ls_stream && -QmfNy183bXiRVyrhyWtq3TwHn79yHEkiAGFr18P7YNzESj: +QmRPX2PWaPGqzoVzqNcQkueijHVzPicjupnD7eLck6Rs21: QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss d1/ -QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy d2/ +Qmf9nCpkCfa8Gtz5m1NJMeHBWcBozKRcbdom338LukPAjy d2/ QmeomffUNfmQy76CQGy9NdmqEnnHU9soCexBnGU3ezPHVH f1 QmNtocSs7MoDkJMc1RkyisCSKvLadujPsfJfSdJ3e1eA1M f2 -QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy: +Qmf9nCpkCfa8Gtz5m1NJMeHBWcBozKRcbdom338LukPAjy: QmbQBUSRL9raZtNXfpTDeaxQapibJEG6qEY8WqAN22aUzd 1024 QmaRGe7bVmVaLmxbrMiVNXqW4pRNNp3xq7hFtyRKA3mtJL a +QmQSLRRd1Lxn6NMsWmmj2g9W3LtSRfmVAVqU3ShneLUrbn bad\u007fname.txt QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss: QmQNd6ubRXaNG6Prov8o6vk3bn6eWsj9FxLGrAVDUAGkGe 128 @@ -195,22 +204,23 @@ EOF ' test_expect_success "'ipfs ls --stream --headers ' succeeds" ' - ipfs ls --stream --headers QmfNy183bXiRVyrhyWtq3TwHn79yHEkiAGFr18P7YNzESj QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss >actual_ls_stream_headers + ipfs ls --stream --headers QmRPX2PWaPGqzoVzqNcQkueijHVzPicjupnD7eLck6Rs21 Qmf9nCpkCfa8Gtz5m1NJMeHBWcBozKRcbdom338LukPAjy QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss >actual_ls_stream_headers ' test_expect_success "'ipfs ls --stream --headers ' output looks good" ' cat <<-\EOF >expected_ls_stream_headers && -QmfNy183bXiRVyrhyWtq3TwHn79yHEkiAGFr18P7YNzESj: +QmRPX2PWaPGqzoVzqNcQkueijHVzPicjupnD7eLck6Rs21: Hash Size Name QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss - d1/ -QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy - d2/ +Qmf9nCpkCfa8Gtz5m1NJMeHBWcBozKRcbdom338LukPAjy - d2/ QmeomffUNfmQy76CQGy9NdmqEnnHU9soCexBnGU3ezPHVH 5 f1 QmNtocSs7MoDkJMc1RkyisCSKvLadujPsfJfSdJ3e1eA1M 5 f2 -QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy: +Qmf9nCpkCfa8Gtz5m1NJMeHBWcBozKRcbdom338LukPAjy: Hash Size Name QmbQBUSRL9raZtNXfpTDeaxQapibJEG6qEY8WqAN22aUzd 1024 1024 QmaRGe7bVmVaLmxbrMiVNXqW4pRNNp3xq7hFtyRKA3mtJL 6 a +QmQSLRRd1Lxn6NMsWmmj2g9W3LtSRfmVAVqU3ShneLUrbn 8 bad\u007fname.txt QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss: Hash Size Name From 306dfb34a14b0c00958b467f0df3366f816beaad Mon Sep 17 00:00:00 2001 From: gammazero Date: Fri, 18 Dec 2020 17:23:30 -0800 Subject: [PATCH 073/116] additional escape --- core/commands/name/publish.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/commands/name/publish.go b/core/commands/name/publish.go index abf1ce34e5b..e220efa7fc7 100644 --- a/core/commands/name/publish.go +++ b/core/commands/name/publish.go @@ -154,7 +154,7 @@ Alternatively, publish an using a valid PeerID (as listed by if quieter { _, err = fmt.Fprintln(w, cmdenv.EscNonPrint(ie.Name)) } else { - _, err = fmt.Fprintf(w, "Published to %s: %s\n", cmdenv.EscNonPrint(ie.Name), ie.Value) + _, err = fmt.Fprintf(w, "Published to %s: %s\n", cmdenv.EscNonPrint(ie.Name), cmdenv.EscNonPrint(ie.Value)) } return err }), From fcdf77c9b0fe33268ad6048d973143b98ddeb83a Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Sat, 19 Dec 2020 16:16:00 +0700 Subject: [PATCH 074/116] update go-libp2p to v0.13.0 --- go.mod | 17 +-- go.sum | 273 +++++----------------------------------- peering/peering_test.go | 2 +- 3 files changed, 38 insertions(+), 254 deletions(-) diff --git a/go.mod b/go.mod index 8e3c05f59be..49c76e7a239 100644 --- a/go.mod +++ b/go.mod @@ -57,35 +57,36 @@ require ( github.com/ipfs/go-verifcid v0.0.1 github.com/ipfs/interface-go-ipfs-core v0.4.0 github.com/ipld/go-car v0.1.1-0.20201015032735-ff6ccdc46acc + github.com/jbenet/go-fuse-version v0.0.0-20160322195114-6d4c97bcf253 // indirect github.com/jbenet/go-is-domain v1.0.5 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-libp2p v0.12.0 + github.com/libp2p/go-libp2p v0.13.0 github.com/libp2p/go-libp2p-circuit v0.4.0 github.com/libp2p/go-libp2p-connmgr v0.2.4 - github.com/libp2p/go-libp2p-core v0.7.0 + github.com/libp2p/go-libp2p-core v0.8.0 github.com/libp2p/go-libp2p-discovery v0.5.0 github.com/libp2p/go-libp2p-http v0.2.0 github.com/libp2p/go-libp2p-kad-dht v0.11.1 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.3.0 + github.com/libp2p/go-libp2p-mplex v0.4.1 github.com/libp2p/go-libp2p-noise v0.1.2 github.com/libp2p/go-libp2p-peerstore v0.2.6 github.com/libp2p/go-libp2p-pubsub v0.4.0 github.com/libp2p/go-libp2p-pubsub-router v0.4.0 - github.com/libp2p/go-libp2p-quic-transport v0.9.3 + github.com/libp2p/go-libp2p-quic-transport v0.10.0 github.com/libp2p/go-libp2p-record v0.1.3 github.com/libp2p/go-libp2p-routing-helpers v0.2.3 github.com/libp2p/go-libp2p-secio v0.2.2 - github.com/libp2p/go-libp2p-swarm v0.3.1 - github.com/libp2p/go-libp2p-testing v0.3.0 + github.com/libp2p/go-libp2p-swarm v0.4.0 + github.com/libp2p/go-libp2p-testing v0.4.0 github.com/libp2p/go-libp2p-tls v0.1.3 - github.com/libp2p/go-libp2p-yamux v0.4.0 + github.com/libp2p/go-libp2p-yamux v0.5.1 github.com/libp2p/go-socket-activation v0.0.2 github.com/libp2p/go-tcp-transport v0.2.1 - github.com/libp2p/go-ws-transport v0.3.1 + github.com/libp2p/go-ws-transport v0.4.0 github.com/lucas-clemente/quic-go v0.19.3 github.com/mattn/go-runewidth v0.0.9 // indirect github.com/mitchellh/go-homedir v1.1.0 diff --git a/go.sum b/go.sum index 9e835c14042..8d7bf697088 100644 --- a/go.sum +++ b/go.sum @@ -50,7 +50,6 @@ github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 h1:iW0a5 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= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/benbjohnson/clock v1.0.2 h1:Z0CN0Yb4ig9sGPXkvAQcGJfnrrMQ5QYLCMPRi9iD7YE= github.com/benbjohnson/clock v1.0.2/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= github.com/benbjohnson/clock v1.0.3 h1:vkLuvpK4fmtSCuo60+yC63p7y0BmQ8gm5ZXGuBCJyXg= github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= @@ -66,7 +65,6 @@ github.com/bren2010/proquint v0.0.0-20160323162903-38337c27106d/go.mod h1:Jbj8eK 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 h1:A/EVblehb75cUgXA5njHPn0kLAsykn6mJGz7rnmW5W0= 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= @@ -104,7 +102,6 @@ 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-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/v22 v22.0.0 h1:XJIw/+VlJ+87J+doOxznsAWIdmWuViOVhkQamW5YV28= github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= github.com/coreos/go-systemd/v22 v22.1.0 h1:kq/SbG2BCKLkDKkjQf5OWwKWUKj1lgs3lFI4PxnR5lg= github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= @@ -121,11 +118,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davidlazar/go-crypto v0.0.0-20170701192655-dcfb0a7ac018 h1:6xT9KW8zLC5IlbaIF5Q7JNieBoACT7iW0YTxQHR0in0= github.com/davidlazar/go-crypto v0.0.0-20170701192655-dcfb0a7ac018/go.mod h1:rQYf4tfk5sSwFsnDg3qYaBxSjsD9S8+59vW0dKUgme4= github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ= -github.com/dgraph-io/badger v1.6.0-rc1 h1:JphPpoBZJ3WHha133BGYlQqltSGIhV+VsEID0++nN9A= github.com/dgraph-io/badger v1.6.0-rc1/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= -github.com/dgraph-io/badger v1.6.0 h1:DshxFxZWXUcO0xX476VJC07Xsr6ZCBVRHKZ93Oh7Evo= github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= -github.com/dgraph-io/badger v1.6.1 h1:w9pSFNSdq/JPM1N12Fz/F/bzo993Is1W+Q7HjPzi7yg= github.com/dgraph-io/badger v1.6.1/go.mod h1:FRmFw3uxvcpa8zG3Rxs0th+hCLIuaQg8HlNV5bjgnuU= github.com/dgraph-io/badger v1.6.2 h1:mNw0qs90GVgGGWylh0umH5iag1j6n/PeJtNvL6KY/x8= github.com/dgraph-io/badger v1.6.2/go.mod h1:JW2yswe3V058sS0kZ2h/AXeDSqFjxnZcRrVH//y2UQE= @@ -151,7 +145,6 @@ github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6 h1:u/UEqS66A5ckRmS4yNp github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6/go.mod h1:1i71OnUq3iUe1ma7Lr6yG6/rjvM3emb6yoL7xLFzcVQ= 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/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= @@ -161,7 +154,6 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME 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 h1:0gkP6mzaMqkmpcJYCFOLkIBwI7xFExG03bbkOkCvUPI= 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= @@ -174,12 +166,10 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.1.1/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 h1:G8O7TerXerS4F6sx9OV7/nRfJdnXgHZu/S/7F2SN+UE= 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/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I= 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= @@ -187,24 +177,20 @@ github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18h github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/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 h1:28o5sBqPkBsMGnC6b4MvE2TzSr5/AT4c/1fLqVGIwlk= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0 h1:Rd1kQnQu0Hq3qvJppYSG0HtP+f5LPPUiDswTLiEegLg= github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= 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.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 h1:oOuy+ugB+P/kBdUnG5QaMXSIyJ1q38wWSojYCb3z5VQ= 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 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= @@ -214,18 +200,14 @@ github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8l 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= -github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 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.18 h1:lum7VRA9kdlvBi7/v2p7/zcbkduHaCH/SVVyurs7OpY= github.com/google/gopacket v1.1.18/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM= @@ -234,7 +216,6 @@ github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OI github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -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 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -243,12 +224,10 @@ 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/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= 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= @@ -268,7 +247,6 @@ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= 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/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huin/goupnp v1.0.0 h1:wg75sLpL6DZqwHQN6E1Cfk6mtfzS45z8OV+ic+DtHRo= github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= @@ -291,21 +269,15 @@ github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJ 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.2 h1:fqFeeu1EG0lGVrqUo+BVJv7LZV31I4ZsyNthCOMAJRc= github.com/ipfs/go-blockservice v0.1.2/go.mod h1:t+411r7psEUhLueM8C7aPA7cxCclv4O3VsUVxt9kz2I= -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.1.4 h1:Vq+MlsH8000KbbUciRyYMEw/NNP8UAGmcqKi4uWmFGA= github.com/ipfs/go-blockservice v0.1.4/go.mod h1:OTZhFpkgY48kNzbgyvcexW9cHrpjBYIjSR0KoDOFOLU= 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 h1:UIAh32wymBpStoe83YCzwVQQ5Oy/H0FdxvUS6DJDzms= github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= -github.com/ipfs/go-cid v0.0.4 h1:UlfXKrZx1DjZoBhQHmNHLC1fK1dUJDN20Y28A7s+gJ8= github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj6+M= -github.com/ipfs/go-cid v0.0.5 h1:o0Ix8e/ql7Zb5UVUJEUfjsWCIY8t48++9lR8qi6oiJU= 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 h1:ysQJVJA3fNDF1qigJbsSQOdjhVLsOEoPdh0+R97k3jY= github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= @@ -313,38 +285,28 @@ 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 h1:TOxI04l8CmO4zGtesENhzm4PwkFwJXY3rKiYaaMf9fI= github.com/ipfs/go-datastore v0.1.0/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= -github.com/ipfs/go-datastore v0.1.1 h1:F4k0TkTAZGLFzBOrVKDAvch6JZtuN4NHkfdcEZL50aI= 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 h1:SS1t869a6cctoSYmZXUk8eL6AzVXgASmKIWFNQkQ1jU= 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 h1:cwOUcGMLdLPWgu3SlrCckCMznaGADbPqE0r8h768/Dg= github.com/ipfs/go-datastore v0.4.5/go.mod h1:eXTcaaiN6uOlVCLS9GjJUJtlvJfM3xk23w3fyfrmmJs= 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 h1:dxKuqw5T1Jm8OuV+lchA76H9QZFyPKZeLuT6bN42hJQ= github.com/ipfs/go-ds-badger v0.0.5/go.mod h1:g5AuuCGmr7efyzQhLL8MzwqcauPojGPUaHzfGTzuE3s= -github.com/ipfs/go-ds-badger v0.0.7 h1:NMyh88Q50HG6/S2YD58DLkq0c0/ZQPMbSojONH+PRf4= github.com/ipfs/go-ds-badger v0.0.7/go.mod h1:qt0/fWzZDoPW6jpQeqUjR5kBfhDNB65jd9YlmAvpQBk= -github.com/ipfs/go-ds-badger v0.2.1 h1:RsC9DDlwFhFdfT+s2PeC8joxbSp2YMufK8w/RBOxKtk= github.com/ipfs/go-ds-badger v0.2.1/go.mod h1:Tx7l3aTph3FMFrRS838dcSJh+jjA7cX9DrGVwx/NOwE= -github.com/ipfs/go-ds-badger v0.2.3 h1:J27YvAcpuA5IvZUbeBxOcQgqnYHUPxoygc6QxxkodZ4= 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 h1:Hy8jw4rifxtRDrqpvC1yh36oIyE37KDzsUzlHUPOFiU= github.com/ipfs/go-ds-badger v0.2.6/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-leveldb v0.0.1/go.mod h1:feO8V3kubwsEF22n0YRQCffeb79OOYIykR4L04tMOYc= -github.com/ipfs/go-ds-leveldb v0.1.0 h1:OsCuIIh1LMTk4WIQ1UJH7e3j01qlOP+KWVhNS6lBDZY= github.com/ipfs/go-ds-leveldb v0.1.0/go.mod h1:hqAW8y4bwX5LWcCtku2rFNX3vjDZCy5LZCg+cSZvYb8= -github.com/ipfs/go-ds-leveldb v0.4.1 h1:zaoLcP8zs4Aj9k8fA4cowyOyNBIvy9Dnt6hf7mHRY7s= 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= @@ -357,13 +319,11 @@ github.com/ipfs/go-fs-lock v0.0.6/go.mod h1:OTR+Rj9sHiRubJh3dRhD15Juhd/+w6VPOY28 github.com/ipfs/go-graphsync v0.5.1 h1:4fXBRvRKicTgTmCFMmEua/H5jvmAOLgU9Z7PCPWt2ec= github.com/ipfs/go-graphsync v0.5.1/go.mod h1:e2ZxnClqBBYAtd901g9vXMJzS47labjAtOzsWtOzKNk= github.com/ipfs/go-ipfs-blockstore v0.0.1/go.mod h1:d3WClOmRQKFnJ0Jz/jj/zmksX0ma1gROTlovZKBmN08= -github.com/ipfs/go-ipfs-blockstore v0.1.0 h1:V1GZorHFUIB6YgTJQdq7mcaIpUfCM3fCyVi+MTo9O88= github.com/ipfs/go-ipfs-blockstore v0.1.0/go.mod h1:5aD0AvHPi7mZc6Ci1WCAhiBQu2IsfTduLl+422H6Rqw= github.com/ipfs/go-ipfs-blockstore v0.1.4 h1:2SGI6U1B44aODevza8Rde3+dY30Pb+lbcObe1LETxOQ= github.com/ipfs/go-ipfs-blockstore v0.1.4/go.mod h1:Jxm3XMVjh6R17WvxFEiyKBLUGr86HgIYJW/D/MwqeYQ= 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 h1:cHUUxKFQ99pozdahi+uSC/3Y6HeRpi9oTeUHbE27SEw= 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= @@ -374,7 +334,6 @@ github.com/ipfs/go-ipfs-config v0.11.0/go.mod h1:Ei/FLgHGTdPyqCPK0oPCwGTe8VSnsjJ 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 h1:QBg+Ts2zgeemK/dB0saiF/ykzRGgfoFMT90Rzo0OnVU= 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= @@ -397,19 +356,15 @@ github.com/ipfs/go-ipfs-provider v0.4.3/go.mod h1:rcQBVqfblDQRk5LaCtf2uxuKxMJxvK 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-util v0.0.1 h1:Wz9bL2wB2YBJqggkA4dD7oSmqB4cAnpNbGrlHJulv50= 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 h1:ENsxvybwkmke7Z/QJOmeJfoguj6GH3Y0YOaGrfy9Q0I= 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 h1:OVAGlyYT6JPZ0pEfGntFPS40lfrDmaDbQwNHEY2G9Zs= 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= @@ -417,33 +372,22 @@ github.com/ipfs/go-ipld-git v0.0.3 h1:/YjkjCyo5KYRpW+suby8Xh9Cm/iH9dAgGV6qyZ1dGu github.com/ipfs/go-ipld-git v0.0.3/go.mod h1:RuvMXa9qtJpDbqngyICCU/d+cmLFXxLsbIclmD0Lcr0= github.com/ipfs/go-ipns v0.0.2 h1:oq4ErrV4hNQ2Eim257RTYRgfOSV/s8BDaf9iIl4NwFs= github.com/ipfs/go-ipns v0.0.2/go.mod h1:WChil4e0/m9cIINWLxZe1Jtf77oz5L05rO2ei/uKJ5U= -github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= -github.com/ipfs/go-log v1.0.1 h1:5lIEEOQTk/vd1WuPFBRqz2mcp+5G1fMVcW+Ib/H5Hfo= github.com/ipfs/go-log v1.0.1/go.mod h1:HuWlQttfN6FWNHRhlY5yMk/lW7evQC0HHGOxEwMRR8I= -github.com/ipfs/go-log v1.0.2 h1:s19ZwJxH8rPWzypjcDpqPLIyV7BnbLqvpli3iZoqYK0= github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= -github.com/ipfs/go-log v1.0.3 h1:Gg7SUYSZ7BrqaKMwM+hRgcAkKv4QLfzP4XPQt5Sx/OI= 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/v2 v2.0.1 h1:mnR9XFltezAtO8A6tj5U7nKkRzhEQNEw/wT11U2HhPM= github.com/ipfs/go-log/v2 v2.0.1/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0= -github.com/ipfs/go-log/v2 v2.0.2 h1:xguurydRdfKMJjKyxNXNU8lYP0VZH1NUwJRwUorjuEw= github.com/ipfs/go-log/v2 v2.0.2/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0= -github.com/ipfs/go-log/v2 v2.0.3 h1:Q2gXcBoCALyLN/pUQlz1qgu0x3uFV6FzP9oXhpfyJpc= 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 h1:G4TtqN+V9y9HY9TA6BwbCVyyBZ2B9MbCjR2MtGx8FR0= github.com/ipfs/go-log/v2 v2.1.1/go.mod h1:2v2nsGfZsvvAJz13SyFzf9ObaqwHiHxsPLEHntrv9KM= 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 h1:aMdkK9G1hEeNvn3VXfiEMLY0iJnbiQQUHnM0HFJREsE= github.com/ipfs/go-merkledag v0.2.3/go.mod h1:SQiXrtSts3KGNmgOzMICy5c0POOpUNQLvB3ClKnBAlk= -github.com/ipfs/go-merkledag v0.3.0 h1:1bXv/ZRPZLVdij/a33CkXMVdxUdred9sz4xyph+0ls0= github.com/ipfs/go-merkledag v0.3.0/go.mod h1:4pymaZLhSLNVuiCITYrpViD6vmfZ/Ws4n/L9tfNv3S4= -github.com/ipfs/go-merkledag v0.3.1 h1:3UqWINBEr3/N+r6OwgFXAddDP/8zpQX/8J7IGVOCqRQ= 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= @@ -453,7 +397,6 @@ github.com/ipfs/go-metrics-prometheus v0.0.2 h1:9i2iljLg12S78OhC6UAiXi176xvQGiZa 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-path v0.0.7 h1:H06hKMquQ0aYtHiHryOMLpQC1qC3QwXwkahcEVD51Ho= github.com/ipfs/go-path v0.0.7/go.mod h1:6KTKmeRnBXgqrTvzFrPV3CamxcgvXX/4z79tfAd2Sno= github.com/ipfs/go-path v0.0.8 h1:R0k6t9x/pa+g8qzl5apQIPurJFozXhopks3iw3MX+jU= github.com/ipfs/go-path v0.0.8/go.mod h1:VpDkSBKQ9EFQOUgi54Tq/O/tGi8n1RfYNks13M3DEs8= @@ -479,25 +422,23 @@ github.com/ipld/go-ipld-prime v0.5.1-0.20201021195245-109253e8a018/go.mod h1:0xE github.com/ipld/go-ipld-prime-proto v0.0.0-20200922192210-9a2bfd4440a6/go.mod h1:3pHYooM9Ea65jewRwrb2u5uHZCNkNTe9ABsVB+SrkH0= github.com/ipld/go-ipld-prime-proto v0.1.0 h1:j7gjqrfwbT4+gXpHwEx5iMssma3mnctC7YaCimsFP70= github.com/ipld/go-ipld-prime-proto v0.1.0/go.mod h1:11zp8f3sHVgIqtb/c9Kr5ZGqpnCLF1IVTNOez9TopzE= -github.com/jackpal/gateway v1.0.5 h1:qzXWUJfuMdlLMtt0a3Dgt+xkWQiA5itDEITVJtuSwMc= github.com/jackpal/gateway v1.0.5/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQetPfnjA= -github.com/jackpal/go-nat-pmp v1.0.1 h1:i0LektDkO1QlrTm/cSuP+PyBCDnYvjPLGl4LdWEMiaA= 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-fuse-version v0.0.0-20160322195114-6d4c97bcf253 h1:+AUuGGAh/2X3wcomiZvjeTcx5OvGXsfdnIqk3KPM+HE= +github.com/jbenet/go-fuse-version v0.0.0-20160322195114-6d4c97bcf253/go.mod h1:gWtF+3u3zVe5/+I44niTEcU/KmVo2oMyLh0WhxpBT28= github.com/jbenet/go-is-domain v1.0.5 h1:r92uiHbMEJo9Fkey5pMBtZAzjPQWic0ieo7Jw1jEuQQ= github.com/jbenet/go-is-domain v1.0.5/go.mod h1:xbRLRb0S7FgzDBTJlguhDVwLYM/5yNtvktxj2Ttfy7Q= 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= -github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2 h1:vhC1OXXiT9R2pczegwz6moDvuRpggaroAXhPIseh57A= github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2/go.mod h1:8GXXJV31xl8whumTzdZsTt3RnUIiPqzkyf7mxToRCMs= github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABoLk/+KKHggpk= github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPwbGVtZVWC34vc5WLsDk= github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= -github.com/jbenet/goprocess v0.1.3 h1:YKyIEECS/XvcfHtBzxtjBBbWK+MbvA6dG8ASiqwvr10= 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= @@ -522,12 +463,10 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b h1:wxtKgYHEncAU00muMD06dzLiahtGM1eouRNOzVV7tdQ= 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/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -535,7 +474,6 @@ 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/libp2p/go-addr-util v0.0.1 h1:TpTQm9cXVRVSKsYbgQ7GKc3KbbHVTnbostgGaDEP+88= 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= @@ -546,58 +484,44 @@ github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38y 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 h1:aqGmto+ttL/uJgX0JtQI0tD21CIEy5eYd1Hlp0juHY0= 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-eventbus v0.1.0 h1:mlawomSAjjkk97QnYiEmHsLu7E136+2oCWSHRUvMfzQ= 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= -github.com/libp2p/go-flow-metrics v0.0.1 h1:0gxuFd2GuK7IIP5pKljLwps6TvcuYgvG7Atqi3INF5s= github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= -github.com/libp2p/go-flow-metrics v0.0.2 h1:U5TvqfoyR6GVRM+bC15Ux1ltar1kbj6Zw6xOVR02CZs= github.com/libp2p/go-flow-metrics v0.0.2/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= 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.6.1 h1:mxabyJf4l6AmotDOKObwSfBNBWjL5VYXysVFLUMAuB8= github.com/libp2p/go-libp2p v0.6.1/go.mod h1:CTFnWXogryAHjXAKEbOf1OWY+VeAP3lDMZkfEI5sT54= -github.com/libp2p/go-libp2p v0.7.0 h1:qWmciout2lJclKfRlxqdepsQB7JihcbRhgcRcssP4rc= github.com/libp2p/go-libp2p v0.7.0/go.mod h1:hZJf8txWeCduQRDC/WSqBGMxaTHCOYHt2xSU1ivxn0k= -github.com/libp2p/go-libp2p v0.7.4 h1:xVj1oSlN0C+FlxqiLuHC8WruMvq24xxfeVxmNhTG0r0= github.com/libp2p/go-libp2p v0.7.4/go.mod h1:oXsBlTLF1q7pxr+9w6lqzS1ILpyHsaBPniVO7zIHGMw= github.com/libp2p/go-libp2p v0.8.1/go.mod h1:QRNH9pwdbEBpx5DTJYg+qxcVaDMAz3Ee/qDKwXujH5o= -github.com/libp2p/go-libp2p v0.12.0 h1:+xai9RQnQ9l5elFOKvp5wRyjyWisSwEx+6nU2+onpUA= github.com/libp2p/go-libp2p v0.12.0/go.mod h1:FpHZrfC1q7nA8jitvdjKBDF31hguaC676g/nT9PgQM0= +github.com/libp2p/go-libp2p v0.13.0 h1:tDdrXARSghmusdm0nf1U/4M8aj8Rr0V2IzQOXmbzQ3s= +github.com/libp2p/go-libp2p v0.13.0/go.mod h1:pM0beYdACRfHO1WcJlp65WXyG2A6NqYM+t2DTVAJxMo= github.com/libp2p/go-libp2p-asn-util v0.0.0-20200825225859-85005c6cf052 h1:BM7aaOF7RpmNn9+9g6uTjGJ0cTzWr5j9i9IKeun2M8U= 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-autonat v0.0.6/go.mod h1:uZneLdOkZHro35xIhpbtTzLlgYturpu4J5+0cZK3MqE= -github.com/libp2p/go-libp2p-autonat v0.1.0 h1:aCWAu43Ri4nU0ZPO7NyLzUvvfqd0nE3dX0R/ZGYVgOU= github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8= -github.com/libp2p/go-libp2p-autonat v0.1.1 h1:WLBZcIRsjZlWdAZj9CiBSvU2wQXoUOiS1Zk1tM7DTJI= github.com/libp2p/go-libp2p-autonat v0.1.1/go.mod h1:OXqkeGOY2xJVWKAGV2inNF5aKN/djNA3fdpCWloIudE= -github.com/libp2p/go-libp2p-autonat v0.2.0 h1:Kok+0M/4jiz6TTmxtBqAa5tLyHb/U+G/7o/JEeW7Wok= github.com/libp2p/go-libp2p-autonat v0.2.0/go.mod h1:DX+9teU4pEEoZUqR1PiMlqliONQdNbfzE1C718tcViI= -github.com/libp2p/go-libp2p-autonat v0.2.1 h1:T0CRQhrvTBKfBSYw6Xo2K3ixtNpAnRCraxof3AAfgQA= github.com/libp2p/go-libp2p-autonat v0.2.1/go.mod h1:MWtAhV5Ko1l6QBsHQNSuM6b1sRkXrpk0/LqCr+vCVxI= -github.com/libp2p/go-libp2p-autonat v0.2.2 h1:4dlgcEEugTFWSvdG2UIFxhnOMpX76QaZSRAtXmYB8n4= github.com/libp2p/go-libp2p-autonat v0.2.2/go.mod h1:HsM62HkqZmHR2k1xgX34WuWDzk/nBwNHoeyyT4IWV6A= github.com/libp2p/go-libp2p-autonat v0.4.0 h1:3y8XQbpr+ssX8QfZUHekjHCYK64sj6/4hnf/awD4+Ug= github.com/libp2p/go-libp2p-autonat v0.4.0/go.mod h1:YxaJlpr81FhdOv3W3BTconZPfhaYivRdf53g+S2wobk= 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 h1:I96SWjR4rK9irDHcHq3XHN6hawCRTPUADzkJacgZLvk= 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-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 h1:Phzbmrg3BkVzbqd4ZZ149JxCuUWu2wZcXf/Kr6hZJj8= github.com/libp2p/go-libp2p-circuit v0.1.4/go.mod h1:CY67BrEjKNDhdTk8UgBX1Y/H5c3xkAcs3gnksxY7osU= -github.com/libp2p/go-libp2p-circuit v0.2.1 h1:BDiBcQxX/ZJJ/yDl3sqZt1bjj4PkZCEi7IEpwxXr13k= 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= @@ -610,42 +534,29 @@ github.com/libp2p/go-libp2p-core v0.0.4/go.mod h1:jyuCQP356gzfCFtRKyvAbNkyeuxb7O github.com/libp2p/go-libp2p-core v0.2.0/go.mod h1:X0eyB0Gy93v0DZtSYbEM7RnMChm9Uv3j7yRXjO77xSI= github.com/libp2p/go-libp2p-core v0.2.2/go.mod h1:8fcwTbsG2B+lTgRJ1ICZtiM5GWCWZVoVrLaDRvIRng0= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= -github.com/libp2p/go-libp2p-core v0.2.5 h1:iP1PIiIrlRrGbE1fYq2918yBc5NlCH3pFuIPSWU9hds= github.com/libp2p/go-libp2p-core v0.2.5/go.mod h1:6+5zJmKhsf7yHn1RbmYDu08qDUpIUxGdqHuEZckmZOA= -github.com/libp2p/go-libp2p-core v0.3.0 h1:F7PqduvrztDtFsAa/bcheQ3azmNo+Nq7m8hQY5GiUW8= github.com/libp2p/go-libp2p-core v0.3.0/go.mod h1:ACp3DmS3/N64c2jDzcV429ukDpicbL6+TrrxANBjPGw= -github.com/libp2p/go-libp2p-core v0.3.1 h1:hEnSDjScfjYvPHoTgZhC4F62M8K1x1Oco/BY0RZ1N3s= github.com/libp2p/go-libp2p-core v0.3.1/go.mod h1:thvWy0hvaSBhnVBaW37BvzgVV68OUhgJJLAa6almrII= -github.com/libp2p/go-libp2p-core v0.4.0 h1:LjZJP/Yy4q8kc724izkYQ9v6YkAmkKCOaE5jLv/NZRo= github.com/libp2p/go-libp2p-core v0.4.0/go.mod h1:49XGI+kc38oGVwqSBhDEwytaAxgZasHhFfQKibzTls0= -github.com/libp2p/go-libp2p-core v0.5.0 h1:FBQ1fpq2Fo/ClyjojVJ5AKXlKhvNc/B6U0O+7AN1ffE= github.com/libp2p/go-libp2p-core v0.5.0/go.mod h1:49XGI+kc38oGVwqSBhDEwytaAxgZasHhFfQKibzTls0= -github.com/libp2p/go-libp2p-core v0.5.1 h1:6Cu7WljPQtGY2krBlMoD8L/zH3tMUsCbqNFH7cZwCoI= github.com/libp2p/go-libp2p-core v0.5.1/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt5/a35Sm4upn4Y= -github.com/libp2p/go-libp2p-core v0.5.3 h1:b9W3w7AZR2n/YJhG8d0qPFGhGhCWKIvPuJgp4hhc4MM= github.com/libp2p/go-libp2p-core v0.5.3/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt5/a35Sm4upn4Y= 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 h1:IxFH4PmtLlLdPf4fF/i129SnK/C+/v8WEX644MxhC48= 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 h1:u03qofNYTBN+yVg08PuAKylZogVf0xcTEeM8skGf+ak= github.com/libp2p/go-libp2p-core v0.6.0/go.mod h1:txwbVEhHEXikXn9gfC7/UDDw7rkxuX0bJvM49Ykaswo= -github.com/libp2p/go-libp2p-core v0.6.1 h1:XS+Goh+QegCDojUZp00CaPMfiEADCrLjNZskWE7pvqs= 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 h1:4a0TMjrWNTZlNvcqxZmrMRDi/NQWrhwO2pkTuLSQ/IQ= 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 h1:5K3mT+64qDTKbV3yTdbMCzJ7O6wbNsavAEb8iqBvBcI= +github.com/libp2p/go-libp2p-core v0.8.0/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= 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 h1:k9MFy+o2zGDNGsaoZl0MA3iZ75qXxr9OOoAZF+sD5OQ= github.com/libp2p/go-libp2p-crypto v0.1.0/go.mod h1:sPUokVISZiy+nNuTTH/TY+leRSxnFj/2GLjtOTW90hI= github.com/libp2p/go-libp2p-discovery v0.0.5/go.mod h1:YtF20GUxjgoKZ4zmXj8j3Nb2TUSBHFlOCetzYdbZL5I= -github.com/libp2p/go-libp2p-discovery v0.1.0 h1:j+R6cokKcGbnZLf4kcNwpx6mDEUPF3N6SrqMymQhmvs= github.com/libp2p/go-libp2p-discovery v0.1.0/go.mod h1:4F/x+aldVHjHDHuX85x1zWoFTGElt8HnoDzwkFZm29g= -github.com/libp2p/go-libp2p-discovery v0.2.0 h1:1p3YSOq7VsgaL+xVHPi8XAmtGyas6D2J6rWBEfz/aiY= github.com/libp2p/go-libp2p-discovery v0.2.0/go.mod h1:s4VGaxYMbw4+4+tsoQTqh7wfxg97AEdo4GYBt6BadWg= -github.com/libp2p/go-libp2p-discovery v0.3.0 h1:+JnYBRLzZQtRq0mK3xhyjBwHytLmJXMTZkQfbw+UrGA= github.com/libp2p/go-libp2p-discovery v0.3.0/go.mod h1:o03drFnz9BVAZdzC/QUQ+NeQOu38Fu7LJGEOK2gQltw= github.com/libp2p/go-libp2p-discovery v0.5.0 h1:Qfl+e5+lfDgwdrXdu4YNCWyEo3fWuP+WgN9mN0iWviQ= github.com/libp2p/go-libp2p-discovery v0.5.0/go.mod h1:+srtPIU9gDaBNu//UHvcdliKBIcr4SfDcm0/PfPJLug= @@ -669,17 +580,14 @@ github.com/libp2p/go-libp2p-loggables v0.1.0/go.mod h1:EyumB2Y6PrYjr55Q3/tiJ/o3x 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 h1:E1xaJBQnbSiTHGI1gaBKmKhu1TUKkErKJnE8iGvirYI= github.com/libp2p/go-libp2p-mplex v0.2.1/go.mod h1:SC99Rxs8Vuzrf/6WhmH41kNn13TiYdAWNYHrwImKLnE= -github.com/libp2p/go-libp2p-mplex v0.2.2 h1:+Ld7YDAfVERQ0E+qqjE7o6fHwKuM0SqTzYiwN1lVVSA= 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.3.0 h1:CZyqqKP0BSGQyPLvpRQougbfXaaaJZdGgzhCpJNuNSk= github.com/libp2p/go-libp2p-mplex v0.3.0/go.mod h1:l9QWxRbbb5/hQMECEb908GbS9Sm2UAR2KFZKUJEynEs= -github.com/libp2p/go-libp2p-nat v0.0.4 h1:+KXK324yaY701On8a0aGjTnw8467kW3ExKcqW2wwmyw= +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-nat v0.0.4/go.mod h1:N9Js/zVtAXqaeT99cXgTV9e75KpnWCvVOiGzlcHmBbY= -github.com/libp2p/go-libp2p-nat v0.0.5 h1:/mH8pXFVKleflDL1YwqMg27W9GD8kjEx7NY0P6eGc98= 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= @@ -688,7 +596,6 @@ github.com/libp2p/go-libp2p-net v0.0.2/go.mod h1:Yt3zgmlsHOgUWSXmt5V/Jpz9upuJBE8 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.1.1 h1:vqYQWvnIcHpIoWJKC7Al4D6Hgj0H012TuXRhPwSMGpQ= github.com/libp2p/go-libp2p-noise v0.1.1/go.mod h1:QDFLdKX7nluB7DEnlVPbz7xlLHdwHFA9HiohJRr3vwM= github.com/libp2p/go-libp2p-noise v0.1.2 h1:IH9GRihQJTx56obm+GnpdPX4KeVIlvpXrP6xnJ0wxWk= github.com/libp2p/go-libp2p-noise v0.1.2/go.mod h1:9B10b7ueo7TIxZHHcjcDCo5Hd6kfKT2m77by82SFRfE= @@ -699,15 +606,10 @@ github.com/libp2p/go-libp2p-peer v0.2.0/go.mod h1:RCffaCvUyW2CJmG2gAWVqwePwW7JMg 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 h1:wMgajt1uM2tMiqf4M+4qWKVyyFc8SfA+84VV9glZq1M= github.com/libp2p/go-libp2p-peerstore v0.1.3/go.mod h1:BJ9sHlm59/80oSkpWgr1MyY1ciXAXV397W6h1GH/uKI= -github.com/libp2p/go-libp2p-peerstore v0.1.4 h1:d23fvq5oYMJ/lkkbO4oTwBp/JP+I/1m5gZJobNXCE/k= github.com/libp2p/go-libp2p-peerstore v0.1.4/go.mod h1:+4BDbDiiKf4PzpANZDAT+knVdLxvqh7hXOujessqdzs= -github.com/libp2p/go-libp2p-peerstore v0.2.0 h1:XcgJhI8WyUOCbHyRLNEX5542YNj8hnLSJ2G1InRjDhk= github.com/libp2p/go-libp2p-peerstore v0.2.0/go.mod h1:N2l3eVIeAitSg3Pi2ipSrJYnqhVnMNQZo9nkSCuAbnQ= -github.com/libp2p/go-libp2p-peerstore v0.2.1 h1:u+gOfsKgu73ZkGWhvckRm03z9C+iS9TrLqpANweELGs= github.com/libp2p/go-libp2p-peerstore v0.2.1/go.mod h1:NQxhNjWxf1d4w6PihR8btWIRjwRLBr4TYKfNgrUkOPA= -github.com/libp2p/go-libp2p-peerstore v0.2.2 h1:iqc/m03jHn5doXN3+kS6JKvqQRHEltiXljQB85iVHWE= github.com/libp2p/go-libp2p-peerstore v0.2.2/go.mod h1:NQxhNjWxf1d4w6PihR8btWIRjwRLBr4TYKfNgrUkOPA= 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= @@ -719,12 +621,11 @@ github.com/libp2p/go-libp2p-pubsub v0.4.0 h1:YNVRyXqBgv9i4RG88jzoTtkSOaSB45CqHkL github.com/libp2p/go-libp2p-pubsub v0.4.0/go.mod h1:izkeMLvz6Ht8yAISXjx60XUQZMq9ZMe5h2ih4dLIBIQ= 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-quic-transport v0.9.3 h1:e6eLN55agvemeYzdJTzIylVbLD5PJr0RJANr9HM+FVc= -github.com/libp2p/go-libp2p-quic-transport v0.9.3/go.mod h1:STiznVmrLMFPXCrkEbNna/VxgdxBatcK0SA+1FSdxnI= +github.com/libp2p/go-libp2p-quic-transport v0.10.0 h1:koDCbWD9CCHwcHZL3/WEvP2A+e/o5/W5L3QS/2SPMA0= +github.com/libp2p/go-libp2p-quic-transport v0.10.0/go.mod h1:RfJbZ8IqXIhxBRm5hqUEJqjiiY8xmEuq3HUDS993MkA= 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 h1:M50VKzWnmUrk/M5/Dz99qO9Xh4vs8ijsK+7HkJvRP+0= 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= @@ -733,108 +634,85 @@ github.com/libp2p/go-libp2p-routing-helpers v0.2.3 h1:xY61alxJ6PurSi+MXbywZpelvu github.com/libp2p/go-libp2p-routing-helpers v0.2.3/go.mod h1:795bh+9YeoFl99rMASoiVgHdi5bjack0N1+AFAdbvBw= 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 h1:ywzZBsWEEz2KNTn5RtzauEDq5RFEefPsttXYwAWqHng= github.com/libp2p/go-libp2p-secio v0.2.0/go.mod h1:2JdZepB8J5V9mBp79BmwsaPQhRPNN2NrnB2lKQcdy6g= -github.com/libp2p/go-libp2p-secio v0.2.1 h1:eNWbJTdyPA7NxhP7J3c5lT97DC5d+u+IldkgCYFTPVA= 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.2 h1:T4hUpgEs2r371PweU3DuH7EOmBIdTBCwWs+FLcgx3bQ= github.com/libp2p/go-libp2p-swarm v0.2.2/go.mod h1:fvmtQ0T1nErXym1/aa1uJEyN7JzaTNyBcHImCxRpPKU= -github.com/libp2p/go-libp2p-swarm v0.2.3 h1:uVkCb8Blfg7HQ/f30TyHn1g/uCwXsAET7pU0U59gx/A= github.com/libp2p/go-libp2p-swarm v0.2.3/go.mod h1:P2VO/EpxRyDxtChXz/VPVXyTnszHvokHKRhfkEgFKNM= -github.com/libp2p/go-libp2p-swarm v0.2.8 h1:cIUUvytBzNQmGSjnXFlI6UpoBGsaud82mJPIJVfkDlg= 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.3.1 h1:UTobu+oQHGdXTOGpZ4RefuVqYoJXcT0EBtSR74m2LkI= github.com/libp2p/go-libp2p-swarm v0.3.1/go.mod h1:hdv95GWCTmzkgeJpP+GK/9D9puJegb7H57B5hWQR5Kk= +github.com/libp2p/go-libp2p-swarm v0.4.0 h1:hahq/ijRoeH6dgROOM8x7SeaKK5VgjjIr96vdrT+NUA= +github.com/libp2p/go-libp2p-swarm v0.4.0/go.mod h1:XVFcO52VoLoo0eitSxNQWYq4D6sydGOweTOAjJNraCw= 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 h1:WaFRj/t3HdMZGNZqnU2pS7pDRBmMeoDx7/HDNpeyT9U= 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-testing v0.1.2-0.20200422005655-8775583591d8/go.mod h1:Qy8sAncLKpwXtS2dSnDOP8ktexIAHKu+J+pnZOFZLTc= -github.com/libp2p/go-libp2p-testing v0.3.0 h1:ZiBYstPamsi7y6NJZebRudUzsYmVkt998hltyLqf8+g= github.com/libp2p/go-libp2p-testing v0.3.0/go.mod h1:efZkql4UZ7OVsEfaxNHZPzIehtsBXMrXnCfJIgDti5g= +github.com/libp2p/go-libp2p-testing v0.4.0 h1:PrwHRi0IGqOwVQWR3xzgigSlhlLfxgfXgkHxr77EghQ= +github.com/libp2p/go-libp2p-testing v0.4.0/go.mod h1:Q+PFXYoiYFN5CAEG2w3gLPEzotlKsNSbKQ/lImlOWF0= github.com/libp2p/go-libp2p-tls v0.1.3 h1:twKMhMu44jQO+HgQK9X8NHO5HkeJu2QbhLzLJpa8oNM= github.com/libp2p/go-libp2p-tls v0.1.3/go.mod h1:wZfuewxOndz5RTnCAxFliGjvYSDA40sKitV4c50uI1M= 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 h1:PZMS9lhjK9VytzMCW3tWHAXtKXmlURSc3ZdvwEcKCzw= github.com/libp2p/go-libp2p-transport-upgrader v0.1.1/go.mod h1:IEtA6or8JUbsV07qPW4r01GnTenLW4oi3lOPbUMGJJA= -github.com/libp2p/go-libp2p-transport-upgrader v0.2.0 h1:5EhPgQhXZNyfL22ERZTUoVp9UVVbNowWNVtELQaKCHk= 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.0 h1:xwj4h3hJdBrxqMOyMUjwscjoVst0AASTsKtZiTChoHI= +github.com/libp2p/go-libp2p-transport-upgrader v0.4.0/go.mod h1:J4ko0ObtZSmgn5BX5AmegP+dK3CSnU2lMCKsSq/EY0s= 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 h1:Q3XYNiKCC2vIxrvUJL+Jg1kiyeEaIDNKLjgEjo3VQdI= github.com/libp2p/go-libp2p-yamux v0.2.1/go.mod h1:1FBXiHDk1VyRM1C0aez2bCfHQ4vMZKkAQzZbkSQt5fI= -github.com/libp2p/go-libp2p-yamux v0.2.2 h1:eGvbqWqWY9S5lrpe2gA0UCOLCdzCgYSAR3vo/xCsNQg= github.com/libp2p/go-libp2p-yamux v0.2.2/go.mod h1:lIohaR0pT6mOt0AZ0L2dFze9hds9Req3OfS+B+dv4qw= -github.com/libp2p/go-libp2p-yamux v0.2.5 h1:MuyItOqz03oi8npvjgMJxgnhllJLZnO/dKVOpTZ9+XI= github.com/libp2p/go-libp2p-yamux v0.2.5/go.mod h1:Zpgj6arbyQrmZ3wxSZxfBmbdnWtbZ48OpsfmQVTErwA= -github.com/libp2p/go-libp2p-yamux v0.2.7 h1:vzKu0NVtxvEIDGCv6mjKRcK0gipSgaXmJZ6jFv0d/dk= 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 h1:qunEZzWwwmfSBYTtSyd81PlD1TjB5uuWcGYHWVXLbUg= 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 h1:sX4WQPHMhRxJE5UZTfjEuBvlQWXB5Bo3A2JK9ZJ9EM0= +github.com/libp2p/go-libp2p-yamux v0.5.1/go.mod h1:dowuvDu8CRWmr0iqySMiSxK+W0iL5cMVO9S94Y6gkv4= 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 h1:/nBTy5+1yRyY82YaO6HXQRnO5IAGsXTjEJaR3LdTPc0= github.com/libp2p/go-mplex v0.1.0/go.mod h1:SXgmdki2kwCUlCCbfGLEgHjC4pFqhTp0ZoV6aiKgxDU= -github.com/libp2p/go-mplex v0.1.1 h1:huPH/GGRJzmsHR9IZJJsrSwIM5YE2gL4ssgl1YWb/ps= 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 h1:Ov/D+8oBlbRkjBs1R1Iua8hJ8cUfbdiW8EOdZuxcgaI= 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-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 h1:lQ7Uc0kS1wb1EfRxO2Eir/RJoHkHn7t6o+EiwsYIKJA= github.com/libp2p/go-msgio v0.0.6/go.mod h1:4ecVB6d9f4BDSL5fqvPiC4A3KivjWn+Venn/1ALLMWA= -github.com/libp2p/go-nat v0.0.3 h1:l6fKV+p0Xa354EqQOQP+d8CivdLM4kl5GxC1hSc/UeI= github.com/libp2p/go-nat v0.0.3/go.mod h1:88nUEt0k0JD45Bk93NIwDqjlhiOwOoV36GchpcVc1yI= -github.com/libp2p/go-nat v0.0.4 h1:KbizNnq8YIf7+Hn7+VFL/xE0eDrkPru2zIO9NMwL8UQ= 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-netroute v0.1.2/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdmLPL2n9MKbk= github.com/libp2p/go-netroute v0.1.3 h1:1ngWRx61us/EpaKkdqkMjKk/ufr/JlIFYQAxV2XX8Ig= github.com/libp2p/go-netroute v0.1.3/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdmLPL2n9MKbk= -github.com/libp2p/go-openssl v0.0.2 h1:9pP2d3Ubaxkv7ZisLjx9BFwgOGnQdQYnfcH29HNY3ls= github.com/libp2p/go-openssl v0.0.2/go.mod h1:v8Zw2ijCSWBQi8Pq5GAixw6DbFfa9u6VIYDXnvOXkc0= -github.com/libp2p/go-openssl v0.0.3 h1:wjlG7HvQkt4Fq4cfH33Ivpwp0omaElYEi9z26qaIkIk= github.com/libp2p/go-openssl v0.0.3/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= -github.com/libp2p/go-openssl v0.0.4 h1:d27YZvLoTyMhIN4njrkr8zMDOM4lfpHIp6A+TK9fovg= 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-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 h1:7PhkfH73VXfPJYKQ6JwS5I/eVcoyYi9IMNGc6FWpFLw= github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA= github.com/libp2p/go-reuseport v0.0.2 h1:XSG94b1FJfGA01BUrT82imejHQyTxO4jEWqheyCXYvU= github.com/libp2p/go-reuseport v0.0.2/go.mod h1:SPD+5RwGC7rcnzngoYC86GjPzjSywuQyMVAheVBD9nQ= -github.com/libp2p/go-reuseport-transport v0.0.2 h1:WglMwyXyBu61CMkjCCtnmqNqnjib0GIEjMiHTwR/KN4= 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 h1:OZGz0RB620QDGpv300n1zaOcKGGAoGVf8h9txtt/1uM= github.com/libp2p/go-reuseport-transport v0.0.4/go.mod h1:trPa7r/7TJK/d+0hdBLOCGvpQQVOU74OXbNCIMkufGw= @@ -845,15 +723,12 @@ github.com/libp2p/go-socket-activation v0.0.2/go.mod h1:KP44C+yZ7gA8sTxavgaD0b8v 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 h1:714bRJ4Zy9mdhyTLJ+ZKiROmAFwUHpeRidG+q7LTQOg= 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-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 h1:yGlqURmqgNA2fvzjSgZNlHcsd/IulAnKM8Ncu+vlqnw= 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.1 h1:ExZiVQV+h+qL16fzCWtd1HSzPsqWottJ8KXwWaVi8Ns= github.com/libp2p/go-tcp-transport v0.2.1/go.mod h1:zskiJ70MEfWz2MKxvFB/Pv+tPIB1PpPUrHIWQ8aFw7M= @@ -861,31 +736,27 @@ github.com/libp2p/go-testutil v0.0.1/go.mod h1:iAcJc/DKJQanJ5ws2V+u5ywdL2n12X1Wb 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.2.0 h1:MJCw2OrPA9+76YNRvdo1wMnSOxb9Bivj6sVFY1Xrj6w= github.com/libp2p/go-ws-transport v0.2.0/go.mod h1:9BHJz/4Q5A9ludYWKoGCFC5gUElzlHoKzu0yY9p/klM= -github.com/libp2p/go-ws-transport v0.3.0 h1:mjo6pL5aVR9rCjl9wNq3DupbaQlyR61pzoOT2MdtxaA= 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 h1:9tvtQ9xbws6cA5LvqdE6Ne3vcmGB4f1z9SByggk4s0k= +github.com/libp2p/go-ws-transport v0.4.0/go.mod h1:EcIEKqf/7GDjth6ksuS/6p7R49V4CBY6/E7R/iyhYUA= 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 h1:xX8A36vpXb59frIzWFdEgptLMsOANMFq2K7fPRlunYI= github.com/libp2p/go-yamux v1.2.3/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= -github.com/libp2p/go-yamux v1.3.0 h1:FsYzT16Wq2XqUGJsBbOxoz9g+dFklvNi7jN6YFPfl7U= github.com/libp2p/go-yamux v1.3.0/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= -github.com/libp2p/go-yamux v1.3.3 h1:mWuzZRCAeTBFdynLlsYgA/EIeMOLr8XY04wa52NRhsE= github.com/libp2p/go-yamux v1.3.3/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= -github.com/libp2p/go-yamux v1.3.5 h1:ibuz4naPAully0pN6J/kmUARiqLpnDQIzI/8GCOrljg= 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 h1:7nqe0T95T2CWh40IdJ/tp8RMor4ubc9/wYZpB2a/Hx0= 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.0.0 h1:vSGhAy5u6iHBq11ZDcyHH4Blcf9xlBhT4WQDoOE90LU= +github.com/libp2p/go-yamux/v2 v2.0.0/go.mod h1:NVWira5+sVUIU6tu1JWvaRn1dRnG+cawOJiflsAM+7U= github.com/lucas-clemente/quic-go v0.19.3 h1:eCDQqvGBB+kCTkA0XrAFtNe81FMa0/fn4QSoeAbmiF4= github.com/lucas-clemente/quic-go v0.19.3/go.mod h1:ADXpNbTQjq1hIzCpB+y/k5iz4n4z4IwqoLb94Kh5Hu8= github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 h1:2gxZ0XQIU/5z3Z3bUBu+FXuk2pFbkN6tcwi/pjyaDic= 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/marten-seemann/qpack v0.2.1/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2opoCp2jDKb7wc= @@ -900,7 +771,6 @@ github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaa github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= 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.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= @@ -912,9 +782,7 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5 github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4= 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.1.12 h1:WMhc1ik4LNkTg8U9l3hI1LvxKmIL+f1+WV/SZtCbDDA= github.com/miekg/dns v1.1.12/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/miekg/dns v1.1.28 h1:gQhy5bsJa8zTlVI8lywCTZp1lguor+xevFoYlzeCTQY= github.com/miekg/dns v1.1.28/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/miekg/dns v1.1.31 h1:sJFOl9BgwbYAWOGEwr61FU28pqsBNdpRBnhGXtO06Oo= github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= @@ -928,7 +796,6 @@ github.com/minio/sha256-simd v0.1.1 h1:5QHSlgo3nt5yKOJrC7W8w7X+NFl8cMPZm96iu8kKU github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= 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/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= 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= @@ -936,9 +803,7 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 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 h1:ZEw4I2EgPKDJ2iEw0cNmLB3ROrEmkOtXIkaG7wZg+78= 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/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= @@ -950,15 +815,10 @@ github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lg github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= github.com/multiformats/go-multiaddr v0.0.4/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= github.com/multiformats/go-multiaddr v0.1.0/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= -github.com/multiformats/go-multiaddr v0.1.1 h1:rVAztJYMhCQ7vEFr8FvxW3mS+HF2eY/oPbOMeS0ZDnE= github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= -github.com/multiformats/go-multiaddr v0.2.0 h1:lR52sFwcTCuQb6bTfnXF6zA2XfyYvyd+5a9qECv/J90= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= -github.com/multiformats/go-multiaddr v0.2.1 h1:SgG/cw5vqyB5QQe5FPe2TqggU9WtrA9X4nZw7LlVqOI= 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 h1:z1Old9IYcUyMEtSbvwCOJ1jcrmJdU0LYH8aFBvZKzcQ= github.com/multiformats/go-multiaddr v0.3.0/go.mod h1:dF9kph9wfJ+3VLAaeBqo9Of8x4fJxp6ggJGteB8HQTI= github.com/multiformats/go-multiaddr v0.3.1 h1:1bxa+W7j9wZKTZREySx1vPMs2TqrYWjVZ7zE6/XLG1I= github.com/multiformats/go-multiaddr v0.3.1/go.mod h1:uPbspcUPd5AfaP6ql3ujFY+QWzmBD8uLLL4bXW0XfGc= @@ -970,48 +830,33 @@ github.com/multiformats/go-multiaddr-fmt v0.0.1/go.mod h1:aBYjqL4T/7j4Qx+R73XSv/ 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= github.com/multiformats/go-multiaddr-net v0.0.1/go.mod h1:nw6HSxNmCIQH27XPGBuX+d1tnvM7ihcFwHMSstNAVUU= -github.com/multiformats/go-multiaddr-net v0.1.0 h1:ZepO8Ezwovd+7b5XPPDhQhayk1yt0AJpzQBpq9fejx4= github.com/multiformats/go-multiaddr-net v0.1.0/go.mod h1:5JNbcfBOP4dnhoZOv10JJVkJO0pCCEf8mTnipAo2UZQ= -github.com/multiformats/go-multiaddr-net v0.1.1 h1:jFFKUuXTXv+3ARyHZi3XUqQO+YWMKgBdhEvuGRfnL6s= github.com/multiformats/go-multiaddr-net v0.1.1/go.mod h1:5JNbcfBOP4dnhoZOv10JJVkJO0pCCEf8mTnipAo2UZQ= -github.com/multiformats/go-multiaddr-net v0.1.2 h1:P7zcBH9FRETdPkDrylcXVjQLQ2t1JQtNItZULWNWgeg= github.com/multiformats/go-multiaddr-net v0.1.2/go.mod h1:QsWt3XK/3hwvNxZJp92iMQKME1qHfpYmyIjFVsSOY6Y= -github.com/multiformats/go-multiaddr-net v0.1.3 h1:q/IYAvoPKuRzGeERn3uacWgm0LIWkLZBAvO5DxSzq3g= github.com/multiformats/go-multiaddr-net v0.1.3/go.mod h1:ilNnaM9HbmVFqsb/qcNysjCu4PVONlrBZpHIrw/qQuA= -github.com/multiformats/go-multiaddr-net v0.1.4 h1:g6gwydsfADqFvrHoMkS0n9Ok9CG6F7ytOH/bJDkhIOY= 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 h1:MSXRGN0mFymt6B1yo/6BPnIRpLPEnKgQNvVfCX5VDJk= github.com/multiformats/go-multiaddr-net v0.2.0/go.mod h1:gGdH3UXny6U3cKKYCvpXI5rnK7YaOIEOPVDI9tsJbEA= -github.com/multiformats/go-multibase v0.0.1 h1:PN9/v21eLywrFWdFNsFKaU04kLJzuYzmrJR+ubhT9qA= github.com/multiformats/go-multibase v0.0.1/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-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 h1:wrYcW5yxSi3dU07n5jnuS5PrNwyHy0zRHGVoUugWvXg= github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= -github.com/multiformats/go-multihash v0.0.9 h1:aoijQXYYl7Xtb2pUUP68R+ys1TlnlR3eX6wmozr0Hp4= github.com/multiformats/go-multihash v0.0.9/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= -github.com/multiformats/go-multihash v0.0.10 h1:lMoNbh2Ssd9PUF74Nz008KGzGPlfeV6wH3rit5IIGCM= 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 h1:QoBceQYQQtNUuf6s7wHxnE2c8bhbMqhfGzNI032se/I= github.com/multiformats/go-multihash v0.0.14/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= 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 h1:UpO6jrsjqs46mqAK3n6wKRYFhugss9ArzbyUzU+4wkQ= 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.0 h1:6AuNmQVKUkRnddw2YiDjt5Elit40SFxMJkVnhmETXtU= github.com/multiformats/go-multistream v0.2.0/go.mod h1:5GZPQZbkWOLOn3J2y4Y99vVW7vOfsAflxARk3x14o6k= -github.com/multiformats/go-varint v0.0.1 h1:TR/0rdQtnNxuN2IhiB639xC3tWM4IUi7DkTBVTdGW/M= 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= @@ -1022,38 +867,30 @@ github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= 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 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.0 h1:Iw5WCbBcaAAd0fpRb1c9r5YCylv4XDoCSigm1zLevwU= github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= -github.com/onsi/ginkgo v1.12.1 h1:mFwc4LvZ0xpSvDZ3E+k8Yte0hLOMxXUlP+yXtJqkYfQ= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= 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 h1:R1uwffexN6Pr340GtYRIdZmAiN4J+iw6WG4wog1DUXg= github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= 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/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= 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/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 h1:2m16U/rLwVaRdz7ANkHtHTodP3zTP3N451MADg64x5k= 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= @@ -1066,7 +903,6 @@ github.com/prometheus/client_golang v1.2.1/go.mod h1:XMU6Z2MjaRKVu/dC1qupJI9SiNk github.com/prometheus/client_golang v1.7.1 h1:NTGy1Ja9pByO+xAeH/qiWnLrKtr3hJPNjaVUwnjpdpA= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE= 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.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= @@ -1121,16 +957,13 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= 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 h1:pa8hGb/2YqsZKovtsgrwcDH1RZhVbTKCjLp47XpqCDs= 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= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/smola/gocompat v0.2.0 h1:6b1oIMlUXIpz//VKEDzPVBK8KG7beVwmHIUEBIs/Pns= github.com/smola/gocompat v0.2.0/go.mod h1:1B0MlxbmoZNo3h8guHp8HztB3BSYR5itql9qtVc0ypY= github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= @@ -1150,11 +983,8 @@ github.com/src-d/envconfig v1.0.0/go.mod h1:Q9YQZ7BKITldTBnoxsE5gOeB5y66RyPXeue/ 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/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= 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= @@ -1170,13 +1000,11 @@ github.com/urfave/cli/v2 v2.0.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2 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/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= -github.com/warpfork/go-wish v0.0.0-20190328234359-8b3e70f8e830 h1:8kxMKmKzXXL4Ru1nyhvdms/JjWt+3YLpvRb/bAjO/y0= 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-gen v0.0.0-20200123233031-1cdf64d27158 h1:WXhVOwj2USAXB5oMDwRl3piOux2XMV9TANaYxXHdkoE= 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 h1:wSxKhvbN7kUoP0sfRS+w2tWr45qlU8409i94hHLOT8w= github.com/whyrusleeping/cbor-gen v0.0.0-20200710004633-5379fc63235d/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= @@ -1184,15 +1012,11 @@ github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f/go.mod h1:p9UJB6dDgdPgMJZs7UjUOdulKyRr9fqkS+6JKAInPy8= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= -github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo= github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= -github.com/whyrusleeping/go-logging v0.0.1 h1:fwpzlmT0kRC/Fmd0MdmGgJG/CXIZ6gFq46FQZjprUcc= github.com/whyrusleeping/go-logging v0.0.1/go.mod h1:lDPYj54zutzG1XYfHAhcc7oNXEburHQBn+Iqd4yS4vE= -github.com/whyrusleeping/go-notifier v0.0.0-20170827234753-097c5d47330f h1:M/lL30eFZTKnomXY6huvM6G0+gVquFNf6mxghaWlFUg= github.com/whyrusleeping/go-notifier v0.0.0-20170827234753-097c5d47330f/go.mod h1:cZNvX9cFybI01GriPRMXDtczuvUhgbcYr9iCGaNlRv8= github.com/whyrusleeping/go-sysinfo v0.0.0-20190219211824-4a357d4b90b1 h1:ctS9Anw/KozviCCtK6VWMz5kPL9nbQzbQY4yfqlIV4M= github.com/whyrusleeping/go-sysinfo v0.0.0-20190219211824-4a357d4b90b1/go.mod h1:tKH72zYNt/exx6/5IQO6L9LoQ0rEjd5SbbWaDTs9Zso= -github.com/whyrusleeping/mafmt v1.2.8 h1:TCghSl5kkwEE0j+sU/gudyhVMRlpBin8fMBBHg59EbA= github.com/whyrusleeping/mafmt v1.2.8/go.mod h1:faQJFPbLSxzD9xpA02ttW/tS9vZykNvXwGvqIpk20FA= github.com/whyrusleeping/mdns v0.0.0-20180901202407-ef14215e6b30/go.mod h1:j4l84WPFclQPj320J9gp0XwNKBb3U0zt5CBqjPp22G4= github.com/whyrusleeping/mdns v0.0.0-20190826153040-b9b60ed33aa9 h1:Y1/FEOpaCpD21WxrmfeIYCFPuVPRCY2XZTWzTNHGw30= @@ -1209,19 +1033,13 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= 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 h1:8dP3SGL7MPB94crU3bEPplMPe83FI4EouesJUeFHv50= go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA= -go.opencensus.io v0.22.2 h1:75k/FF0Q2YM8QYo07VPddOLBslDt1MZOdEslOHvmzAs= 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 h1:LYy1Hy3MJdrCdMwwzxA/dRok4ejH+RwNGbuoD9fCjto= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5 h1:dntmOdLpSpHlVqbW5Eay97DelsZHe+55D+xC6i0dDS0= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.5.0 h1:OI5t8sDa1Or+q8AeE+yKeB/SDYioSHAgcVljj9JIETY= 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= @@ -1229,23 +1047,17 @@ 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 h1:G3eWbSNIskeRqtsN/1uI5B+eP73y3JUuBsv9AZjehb4= go.uber.org/goleak v0.10.0/go.mod h1:VCZuO8V8mFPlL0F5J5GK1rtHV3DrFcQ1R8ryq7FK0aI= go.uber.org/goleak v1.0.0 h1:qsup4IcBdlmsnGfqyLl4Ntn3C2XCCuKAE7DwHpScyUo= go.uber.org/goleak v1.0.0/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= -go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/multierr v1.4.0 h1:f3WCSC2KzAcBXGATIxAB1E2XuCpNU255wNKZ505qi3E= 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/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= -go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.14.1 h1:nYDKopTbvAPq/NrUVZwT15y2lpROBiLLyoRTbXOYWOo= 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 h1:uFRZXykJGK9lLY4HtgSw44DnIcAM+kRBP7x5m+NpAOM= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= @@ -1269,15 +1081,11 @@ golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8U 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-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200117160349-530e935923ad/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d h1:1ZiEyfaQIg3Qh0EoqpwAakHVhecoE5wlSg5GjnafJGw= golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200423211502-4bdfaf469ed5 h1:Q7tZBpemrlsc2I7IyODzhtallWRSm4Q0d09pL6XbQtU= golang.org/x/crypto v0.0.0-20200423211502-4bdfaf469ed5/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -1298,9 +1106,7 @@ golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTk 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 h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= 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 h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k= @@ -1310,7 +1116,6 @@ golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCc 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.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -1334,11 +1139,8 @@ golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR 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 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 h1:Ao/3l156eZf2AW5wK8a7/smtodRU+gha3+BeqJ69lRk= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190923162816-aa69164e4478 h1:l5EDrHhldLYb3ZRHDUhXF7Om7MvYXnkV9/iQNo1lX6g= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/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-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -1360,11 +1162,8 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ 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-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= 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 h1:WXEvlFVvvGxCJLG6REjsT03iWnKLEWinaScsxF2Vm2o= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 h1:qwRHBd0NqMbJxfbotnDhm2ByMI1Shq4Y6oRJo21SGJA= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1408,7 +1207,6 @@ golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/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 h1:/WDfKMnPU+m5M4xB+6x4kaepxRw6jWvR5iDRdvjHgy8= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1417,7 +1215,6 @@ golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7w 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 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -1435,7 +1232,6 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/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-20190328211700-ab21143f2384 h1:TFlARGu6Czu1z7q93HTxcP1P+/ZFC/IKythI5RzrnRg= 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-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= @@ -1451,13 +1247,10 @@ 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 h1:0FYNp0PF9kFm/ZUrvcJiQ12IUJJG7iAc6Cu01wbKrbU= 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 h1:kDxGY2VmgABOe55qheT/TFqUMtcTHnomIPS1iv3G4Ms= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216052735-49a3e744a425 h1:VvQyQJN0tSuecqgcIxMWnnfG5kSmgy9KZR9sW3W5QeA= 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-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= @@ -1466,9 +1259,7 @@ golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200827010519-17fd2f27a9e3 h1:r3P/5xOq/dK1991B65Oy6E1fRF/2d/fSYZJ/fXGVfJc= golang.org/x/tools v0.0.0-20200827010519-17fd2f27a9e3/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 h1:/atklqdjdhuosWIl6AIbOeHJjicWYPqR9bpxqxYG2pA= 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= @@ -1507,7 +1298,6 @@ google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvx 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-20200212174721-66ed5ce911ce h1:1mbrb1tUU+Zmt5C94IGKADBTJZjZXAd+BubWi7r9EiI= google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= @@ -1521,7 +1311,6 @@ google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac 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 h1:zvIju4sqAGvwKspUQOhwnpcqSbzi7/H6QomNNjTL4sk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.28.1/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.31.1 h1:SfXqXS5hkufcdZ/mHtYCh53P2b+92WQq/DZcKLgsFRs= @@ -1530,10 +1319,8 @@ google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLY 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 h1:qdOKuR/EIArgaWNjetjgTzgVTAZ+S/WXVrq9HW9zimw= 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 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= 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.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= @@ -1541,12 +1328,10 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= 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 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 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/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/src-d/go-cli.v0 v0.0.0-20181105080154-d492247bbc0d/go.mod h1:z+K8VcOYVYcSwSjGebuDL6176A1XskgbtNl64NSg+n8= @@ -1554,10 +1339,8 @@ gopkg.in/src-d/go-log.v1 v1.0.1/go.mod h1:GN34hKP0g305ysm2/hctJ0Y8nWP3zxXXJ8GFab 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/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/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.5 h1:ymVxjfMaHvXD8RqPRmzHHsB3VvucivSkIAvJFDI5O3c= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/peering/peering_test.go b/peering/peering_test.go index 1f21b7816a2..3bfdd9d946e 100644 --- a/peering/peering_test.go +++ b/peering/peering_test.go @@ -90,7 +90,7 @@ func TestPeeringService(t *testing.T) { // All conns to peer should eventually close. for _, c := range conns { require.Eventually(t, func() bool { - s, err := c.NewStream() + s, err := c.NewStream(context.Background()) if s != nil { _ = s.Reset() } From 09178aa717689a0ef9fd2042ad355320a16ffb35 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Fri, 1 Jan 2021 21:39:42 +0100 Subject: [PATCH 075/116] feat(gw): support inlined DNSLink names with TLS Problem statement and rationale for doing this can be found under "Option C" at: https://github.com/ipfs/in-web-browsers/issues/169 TLDR is: `https://dweb.link/ipns/my.v-long.example.com` can be loaded from a subdomain gateway with a wildcard TLS cert if represented as a single DNS label: `https://my-v--long-example-com.ipns.dweb.link` --- core/corehttp/hostname.go | 125 ++++++++++++++++++---- core/corehttp/hostname_test.go | 111 ++++++++++++++++--- docs/config.md | 3 +- test/sharness/t0114-gateway-subdomains.sh | 20 +++- 4 files changed, 218 insertions(+), 41 deletions(-) diff --git a/core/corehttp/hostname.go b/core/corehttp/hostname.go index 4a531a4d371..7e2d07821c7 100644 --- a/core/corehttp/hostname.go +++ b/core/corehttp/hostname.go @@ -91,7 +91,7 @@ func HostnameOption() ServeOption { if gw.UseSubdomains { // Yes, redirect if applicable // Example: dweb.link/ipfs/{cid} → {cid}.ipfs.dweb.link - newURL, err := toSubdomainURL(host, r.URL.Path, r) + newURL, err := toSubdomainURL(host, r.URL.Path, r, coreAPI) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return @@ -126,7 +126,7 @@ func HostnameOption() ServeOption { // Not a whitelisted path // Try DNSLink, if it was not explicitly disabled for the hostname - if !gw.NoDNSLink && isDNSLinkRequest(r.Context(), coreAPI, host) { + if !gw.NoDNSLink && isDNSLinkName(r.Context(), coreAPI, host) { // rewrite path and handle as DNSLink r.URL.Path = "/ipns/" + stripPort(host) + r.URL.Path childMux.ServeHTTP(w, withHostnameContext(r, host)) @@ -139,8 +139,10 @@ func HostnameOption() ServeOption { } // HTTP Host check: is this one of our subdomain-based "known gateways"? - // Example: {cid}.ipfs.localhost, {cid}.ipfs.dweb.link - if gw, hostname, ns, rootID, ok := knownSubdomainDetails(host, knownGateways); ok { + // IPFS details extracted from the host: {rootID}.{ns}.{gwHostname} + // /ipfs/ example: {cid}.ipfs.localhost:8080, {cid}.ipfs.dweb.link + // /ipns/ example: {libp2p-key}.ipns.localhost:8080, {inlined-dnslink-fqdn}.ipns.dweb.link + if gw, gwHostname, ns, rootID, ok := knownSubdomainDetails(host, knownGateways); ok { // Looks like we're using a known gateway in subdomain mode. // Assemble original path prefix. @@ -156,14 +158,14 @@ func HostnameOption() ServeOption { // Check if rootID is a valid CID if rootCID, err := cid.Decode(rootID); err == nil { // Do we need to redirect root CID to a canonical DNS representation? - dnsCID, err := toDNSPrefix(rootID, rootCID) + dnsCID, err := toDNSLabel(rootID, rootCID) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } if !strings.HasPrefix(r.Host, dnsCID) { dnsPrefix := "/" + ns + "/" + dnsCID - newURL, err := toSubdomainURL(hostname, dnsPrefix+r.URL.Path, r) + newURL, err := toSubdomainURL(gwHostname, dnsPrefix+r.URL.Path, r, coreAPI) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return @@ -179,7 +181,7 @@ func HostnameOption() ServeOption { // Do we need to fix multicodec in PeerID represented as CIDv1? if isPeerIDNamespace(ns) { if rootCID.Type() != cid.Libp2pKey { - newURL, err := toSubdomainURL(hostname, pathPrefix+r.URL.Path, r) + newURL, err := toSubdomainURL(gwHostname, pathPrefix+r.URL.Path, r, coreAPI) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return @@ -191,13 +193,36 @@ func HostnameOption() ServeOption { } } } + } else { // rootID is not a CID.. + + // Check if rootID is a single DNS label with an inlined + // DNSLink FQDN a single DNS label. We support this so + // loading DNSLink names over TLS "just works" on public + // HTTP gateways. + // + // Rationale for doing this can be found under "Option C" + // at: https://github.com/ipfs/in-web-browsers/issues/169 + // + // TLDR is: + // https://dweb.link/ipns/my.v-long.example.com + // can be loaded from a subdomain gateway with a wildcard + // TLS cert if represented as a single DNS label: + // https://my-v--long-example-com.ipns.dweb.link + if ns == "ipns" && !strings.Contains(rootID, ".") { + // my-v--long-example-com → my.v-long.example.com + dnslinkFQDN := toDNSLinkFQDN(rootID) + if isDNSLinkName(r.Context(), coreAPI, dnslinkFQDN) { + // update path prefix to use real FQDN with DNSLink + pathPrefix = "/ipns/" + dnslinkFQDN + } + } } // Rewrite the path to not use subdomains r.URL.Path = pathPrefix + r.URL.Path // Serve path request - childMux.ServeHTTP(w, withHostnameContext(r, hostname)) + childMux.ServeHTTP(w, withHostnameContext(r, gwHostname)) return } // We don't have a known gateway. Fallback on DNSLink lookup @@ -206,7 +231,7 @@ func HostnameOption() ServeOption { // 1. is wildcard DNSLink enabled (Gateway.NoDNSLink=false)? // 2. does Host header include a fully qualified domain name (FQDN)? // 3. does DNSLink record exist in DNS? - if !cfg.Gateway.NoDNSLink && isDNSLinkRequest(r.Context(), coreAPI, host) { + if !cfg.Gateway.NoDNSLink && isDNSLinkName(r.Context(), coreAPI, host) { // rewrite path and handle as DNSLink r.URL.Path = "/ipns/" + stripPort(host) + r.URL.Path childMux.ServeHTTP(w, withHostnameContext(r, host)) @@ -305,9 +330,10 @@ func isKnownHostname(hostname string, knownGateways gatewayHosts) (gw *config.Ga } // Parses Host header and looks for a known gateway matching subdomain host. -// If found, returns GatewaySpec and subdomain components. +// If found, returns GatewaySpec and subdomain components extracted from Host +// header: {rootID}.{ns}.{gwHostname} // Note: hostname is host + optional port -func knownSubdomainDetails(hostname string, knownGateways gatewayHosts) (gw *config.GatewaySpec, knownHostname, ns, rootID string, ok bool) { +func knownSubdomainDetails(hostname string, knownGateways gatewayHosts) (gw *config.GatewaySpec, gwHostname, ns, rootID string, ok bool) { labels := strings.Split(hostname, ".") // Look for FQDN of a known gateway hostname. // Example: given "dist.ipfs.io.ipns.dweb.link": @@ -336,9 +362,8 @@ func knownSubdomainDetails(hostname string, knownGateways gatewayHosts) (gw *con return nil, "", "", "", false } -// isDNSLinkRequest returns bool that indicates if request -// should return data from content path listed in DNSLink record (if exists) -func isDNSLinkRequest(ctx context.Context, ipfs iface.CoreAPI, host string) bool { +// isDNSLinkName returns bool if a valid DNS TXT record exist for provided host +func isDNSLinkName(ctx context.Context, ipfs iface.CoreAPI, host string) bool { fqdn := stripPort(host) if len(fqdn) == 0 && !isd.IsDomain(fqdn) { return false @@ -368,8 +393,8 @@ func isPeerIDNamespace(ns string) bool { } } -// Converts an identifier to DNS-safe representation that fits in 63 characters -func toDNSPrefix(rootID string, rootCID cid.Cid) (prefix string, err error) { +// Converts a CID to DNS-safe representation that fits in 63 characters +func toDNSLabel(rootID string, rootCID cid.Cid) (dnsCID string, err error) { // Return as-is if things fit if len(rootID) <= dnsLabelMaxLength { return rootID, nil @@ -388,12 +413,45 @@ func toDNSPrefix(rootID string, rootCID cid.Cid) (prefix string, err error) { return "", fmt.Errorf("CID incompatible with DNS label length limit of 63: %s", rootID) } +// Returns true if HTTP request involves TLS certificate. +// See https://github.com/ipfs/in-web-browsers/issues/169 to uderstand how it +// impacts DNSLink websites on public gateways. +func isHTTPSRequest(r *http.Request) bool { + // X-Forwarded-Proto if added by a reverse proxy + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto + xproto := r.Header.Get("X-Forwarded-Proto") + // Is request a native TLS (not used atm, but future-proofing) + // or a proxied HTTPS (eg. go-ipfs behind nginx at a public gw)? + return r.URL.Scheme == "https" || xproto == "https" +} + +// Converts a FQDN to DNS-safe representation that fits in 63 characters: +// my.v-long.example.com → my-v--long-example-com +func toDNSLinkDNSLabel(fqdn string) (dnsLabel string, err error) { + dnsLabel = strings.ReplaceAll(fqdn, "-", "--") + dnsLabel = strings.ReplaceAll(dnsLabel, ".", "-") + if len(dnsLabel) > dnsLabelMaxLength { + return "", fmt.Errorf("DNSLink representation incompatible with DNS label length limit of 63: %s", dnsLabel) + } + return dnsLabel, nil +} + +// Converts a DNS-safe representation of DNSLink FQDN to real FQDN: +// my-v--long-example-com → my.v-long.example.com +func toDNSLinkFQDN(dnsLabel string) (fqdn string) { + fqdn = strings.ReplaceAll(dnsLabel, "--", "@") // @ placeholder is unused in DNS labels + fqdn = strings.ReplaceAll(fqdn, "-", ".") + fqdn = strings.ReplaceAll(fqdn, "@", "-") + return fqdn +} + // Converts a hostname/path to a subdomain-based URL, if applicable. -func toSubdomainURL(hostname, path string, r *http.Request) (redirURL string, err error) { +func toSubdomainURL(hostname, path string, r *http.Request, ipfs iface.CoreAPI) (redirURL string, err error) { var scheme, ns, rootID, rest string query := r.URL.RawQuery parts := strings.SplitN(path, "/", 4) + isHTTPS := isHTTPSRequest(r) safeRedirectURL := func(in string) (out string, err error) { safeURI, err := url.ParseRequestURI(in) if err != nil { @@ -402,10 +460,7 @@ func toSubdomainURL(hostname, path string, r *http.Request) (redirURL string, er return safeURI.String(), nil } - // Support X-Forwarded-Proto if added by a reverse proxy - // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto - xproto := r.Header.Get("X-Forwarded-Proto") - if xproto == "https" { + if isHTTPS { scheme = "https:" } else { scheme = "http:" @@ -475,10 +530,36 @@ func toSubdomainURL(hostname, path string, r *http.Request) (redirURL string, er } // 2. Make sure CID fits in a DNS label, adjust encoding if needed // (https://github.com/ipfs/go-ipfs/issues/7318) - rootID, err = toDNSPrefix(rootID, rootCID) + rootID, err = toDNSLabel(rootID, rootCID) if err != nil { return "", err } + } else { // rootID is not a CID + + // Check if rootID is a FQDN with DNSLink and convert it to TLS-safe + // representation that fits in a single DNS label. We support this so + // loading DNSLink names over TLS "just works" on public HTTP gateways + // that pass 'https' in X-Forwarded-Proto to go-ipfs. + // + // Rationale can be found under "Option C" + // at: https://github.com/ipfs/in-web-browsers/issues/169 + // + // TLDR is: + // /ipns/my.v-long.example.com + // can be loaded from a subdomain gateway with a wildcard TLS cert if + // represented as a single DNS label: + // https://my-v--long-example-com.ipns.dweb.link + if isHTTPS && ns == "ipns" && strings.Contains(rootID, ".") { + if isDNSLinkName(r.Context(), ipfs, rootID) { + // my.v-long.example.com → my-v--long-example-com + dnsLabel, err := toDNSLinkDNSLabel(rootID) + if err != nil { + return "", err + } + // update path prefix to use real FQDN with DNSLink + rootID = dnsLabel + } + } } return safeRedirectURL(fmt.Sprintf( diff --git a/core/corehttp/hostname_test.go b/core/corehttp/hostname_test.go index 3a316ede5f1..f469a7720cd 100644 --- a/core/corehttp/hostname_test.go +++ b/core/corehttp/hostname_test.go @@ -2,41 +2,121 @@ package corehttp import ( "errors" + "net/http" "net/http/httptest" "testing" cid "github.com/ipfs/go-cid" config "github.com/ipfs/go-ipfs-config" + files "github.com/ipfs/go-ipfs-files" + coreapi "github.com/ipfs/go-ipfs/core/coreapi" + path "github.com/ipfs/go-path" ) func TestToSubdomainURL(t *testing.T) { - r := httptest.NewRequest("GET", "http://request-stub.example.com", nil) + ns := mockNamesys{} + n, err := newNodeWithMockNamesys(ns) + if err != nil { + t.Fatal(err) + } + coreAPI, err := coreapi.NewCoreAPI(n) + if err != nil { + t.Fatal(err) + } + testCID, err := coreAPI.Unixfs().Add(n.Context(), files.NewBytesFile([]byte("fnord"))) + if err != nil { + t.Fatal(err) + } + ns["/ipns/dnslink.long-name.example.com"] = path.FromString(testCID.String()) + ns["/ipns/dnslink.too-long.f1siqrebi3vir8sab33hu5vcy008djegvay6atmz91ojesyjs8lx350b7y7i1nvyw2haytfukfyu2f2x4tocdrfa0zgij6p4zpl4u5o.example.com"] = path.FromString(testCID.String()) + httpRequest := httptest.NewRequest("GET", "http://127.0.0.1:8080", nil) + httpsRequest := httptest.NewRequest("GET", "https://https-request-stub.example.com", nil) + httpsProxiedRequest := httptest.NewRequest("GET", "http://proxied-https-request-stub.example.com", nil) + httpsProxiedRequest.Header.Set("X-Forwarded-Proto", "https") + for _, test := range []struct { // in: - hostname string - path string + request *http.Request + gwHostname string + path string // out: url string err error }{ // DNSLink - {"localhost", "/ipns/dnslink.io", "http://dnslink.io.ipns.localhost/", nil}, + {httpRequest, "localhost", "/ipns/dnslink.io", "http://dnslink.io.ipns.localhost/", nil}, // Hostname with port - {"localhost:8080", "/ipns/dnslink.io", "http://dnslink.io.ipns.localhost:8080/", nil}, + {httpRequest, "localhost:8080", "/ipns/dnslink.io", "http://dnslink.io.ipns.localhost:8080/", nil}, // CIDv0 → CIDv1base32 - {"localhost", "/ipfs/QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n", "http://bafybeif7a7gdklt6hodwdrmwmxnhksctcuav6lfxlcyfz4khzl3qfmvcgu.ipfs.localhost/", nil}, + {httpRequest, "localhost", "/ipfs/QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n", "http://bafybeif7a7gdklt6hodwdrmwmxnhksctcuav6lfxlcyfz4khzl3qfmvcgu.ipfs.localhost/", nil}, // CIDv1 with long sha512 - {"localhost", "/ipfs/bafkrgqe3ohjcjplc6n4f3fwunlj6upltggn7xqujbsvnvyw764srszz4u4rshq6ztos4chl4plgg4ffyyxnayrtdi5oc4xb2332g645433aeg", "", errors.New("CID incompatible with DNS label length limit of 63: kf1siqrebi3vir8sab33hu5vcy008djegvay6atmz91ojesyjs8lx350b7y7i1nvyw2haytfukfyu2f2x4tocdrfa0zgij6p4zpl4u5oj")}, + {httpRequest, "localhost", "/ipfs/bafkrgqe3ohjcjplc6n4f3fwunlj6upltggn7xqujbsvnvyw764srszz4u4rshq6ztos4chl4plgg4ffyyxnayrtdi5oc4xb2332g645433aeg", "", errors.New("CID incompatible with DNS label length limit of 63: kf1siqrebi3vir8sab33hu5vcy008djegvay6atmz91ojesyjs8lx350b7y7i1nvyw2haytfukfyu2f2x4tocdrfa0zgij6p4zpl4u5oj")}, // PeerID as CIDv1 needs to have libp2p-key multicodec - {"localhost", "/ipns/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", "http://k2k4r8n0flx3ra0y5dr8fmyvwbzy3eiztmtq6th694k5a3rznayp3e4o.ipns.localhost/", nil}, - {"localhost", "/ipns/bafybeickencdqw37dpz3ha36ewrh4undfjt2do52chtcky4rxkj447qhdm", "http://k2k4r8l9ja7hkzynavdqup76ou46tnvuaqegbd04a4o1mpbsey0meucb.ipns.localhost/", nil}, + {httpRequest, "localhost", "/ipns/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", "http://k2k4r8n0flx3ra0y5dr8fmyvwbzy3eiztmtq6th694k5a3rznayp3e4o.ipns.localhost/", nil}, + {httpRequest, "localhost", "/ipns/bafybeickencdqw37dpz3ha36ewrh4undfjt2do52chtcky4rxkj447qhdm", "http://k2k4r8l9ja7hkzynavdqup76ou46tnvuaqegbd04a4o1mpbsey0meucb.ipns.localhost/", nil}, // PeerID: ed25519+identity multihash → CIDv1Base36 - {"localhost", "/ipns/12D3KooWFB51PRY9BxcXSH6khFXw1BZeszeLDy7C8GciskqCTZn5", "http://k51qzi5uqu5di608geewp3nqkg0bpujoasmka7ftkyxgcm3fh1aroup0gsdrna.ipns.localhost/", nil}, - {"sub.localhost", "/ipfs/QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n", "http://bafybeif7a7gdklt6hodwdrmwmxnhksctcuav6lfxlcyfz4khzl3qfmvcgu.ipfs.sub.localhost/", nil}, + {httpRequest, "localhost", "/ipns/12D3KooWFB51PRY9BxcXSH6khFXw1BZeszeLDy7C8GciskqCTZn5", "http://k51qzi5uqu5di608geewp3nqkg0bpujoasmka7ftkyxgcm3fh1aroup0gsdrna.ipns.localhost/", nil}, + {httpRequest, "sub.localhost", "/ipfs/QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n", "http://bafybeif7a7gdklt6hodwdrmwmxnhksctcuav6lfxlcyfz4khzl3qfmvcgu.ipfs.sub.localhost/", nil}, + // HTTPS requires DNSLink name to fit in a single DNS label – see "Option C" from https://github.com/ipfs/in-web-browsers/issues/169 + {httpRequest, "dweb.link", "/ipns/dnslink.long-name.example.com", "http://dnslink.long-name.example.com.ipns.dweb.link/", nil}, + {httpsRequest, "dweb.link", "/ipns/dnslink.long-name.example.com", "https://dnslink-long--name-example-com.ipns.dweb.link/", nil}, + {httpsProxiedRequest, "dweb.link", "/ipns/dnslink.long-name.example.com", "https://dnslink-long--name-example-com.ipns.dweb.link/", nil}, } { - url, err := toSubdomainURL(test.hostname, test.path, r) + url, err := toSubdomainURL(test.gwHostname, test.path, test.request, coreAPI) if url != test.url || !equalError(err, test.err) { - t.Errorf("(%s, %s) returned (%s, %v), expected (%s, %v)", test.hostname, test.path, url, err, test.url, test.err) + t.Errorf("(%s, %s) returned (%s, %v), expected (%s, %v)", test.gwHostname, test.path, url, err, test.url, test.err) + } + } +} + +func TestToDNSLinkDNSLabel(t *testing.T) { + for _, test := range []struct { + in string + out string + err error + }{ + {"dnslink.long-name.example.com", "dnslink-long--name-example-com", nil}, + {"dnslink.too-long.f1siqrebi3vir8sab33hu5vcy008djegvay6atmz91ojesyjs8lx350b7y7i1nvyw2haytfukfyu2f2x4tocdrfa0zgij6p4zpl4u5o.example.com", "", errors.New("DNSLink representation incompatible with DNS label length limit of 63: dnslink-too--long-f1siqrebi3vir8sab33hu5vcy008djegvay6atmz91ojesyjs8lx350b7y7i1nvyw2haytfukfyu2f2x4tocdrfa0zgij6p4zpl4u5o-example-com")}, + } { + out, err := toDNSLinkDNSLabel(test.in) + if out != test.out || !equalError(err, test.err) { + t.Errorf("(%s) returned (%s, %v), expected (%s, %v)", test.in, out, err, test.out, test.err) + } + } +} + +func TestToDNSLinkFQDN(t *testing.T) { + for _, test := range []struct { + in string + out string + }{ + {"singlelabel", "singlelabel"}, + {"docs-ipfs-io", "docs.ipfs.io"}, + {"dnslink-long--name-example-com", "dnslink.long-name.example.com"}, + } { + out := toDNSLinkFQDN(test.in) + if out != test.out { + t.Errorf("(%s) returned (%s), expected (%s)", test.in, out, test.out) + } + } +} + +func TestIsHTTPSRequest(t *testing.T) { + httpRequest := httptest.NewRequest("GET", "http://127.0.0.1:8080", nil) + httpsRequest := httptest.NewRequest("GET", "https://https-request-stub.example.com", nil) + httpsProxiedRequest := httptest.NewRequest("GET", "http://proxied-https-request-stub.example.com", nil) + httpsProxiedRequest.Header.Set("X-Forwarded-Proto", "https") + for _, test := range []struct { + in *http.Request + out bool + }{ + {httpRequest, false}, + {httpsRequest, true}, + {httpsProxiedRequest, true}, + } { + out := isHTTPSRequest(test.in) + if out != test.out { + t.Errorf("(%+v): returned %t, expected %t", test.in, out, test.out) } } } @@ -77,10 +157,9 @@ func TestPortStripping(t *testing.T) { t.Errorf("(%s): returned '%s', expected '%s'", test.in, out, test.out) } } - } -func TestDNSPrefix(t *testing.T) { +func TestToDNSLabel(t *testing.T) { for _, test := range []struct { in string out string @@ -96,7 +175,7 @@ func TestDNSPrefix(t *testing.T) { {"bafkrgqe3ohjcjplc6n4f3fwunlj6upltggn7xqujbsvnvyw764srszz4u4rshq6ztos4chl4plgg4ffyyxnayrtdi5oc4xb2332g645433aeg", "", errors.New("CID incompatible with DNS label length limit of 63: kf1siqrebi3vir8sab33hu5vcy008djegvay6atmz91ojesyjs8lx350b7y7i1nvyw2haytfukfyu2f2x4tocdrfa0zgij6p4zpl4u5oj")}, } { inCID, _ := cid.Decode(test.in) - out, err := toDNSPrefix(test.in, inCID) + out, err := toDNSLabel(test.in, inCID) if out != test.out || !equalError(err, test.err) { t.Errorf("(%s): returned (%s, %v) expected (%s, %v)", test.in, out, err, test.out, test.err) } diff --git a/docs/config.md b/docs/config.md index 2ea82bca39a..d2806a8a7d0 100644 --- a/docs/config.md +++ b/docs/config.md @@ -709,8 +709,9 @@ Below is a list of the most common public gateway setups. ``` **Backward-compatible:** this feature enables automatic redirects from content paths to subdomains: `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://`. The NGINX directive is `proxy_set_header X-Forwarded-Proto "https";`.: + **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` **X-Forwarded-Host:** we also support `X-Forwarded-Host: example.com` if you want to override subdomain gateway host from the original request: `http://dweb.link/ipfs/{cid}` → `http://{cid}.ipfs.example.com` diff --git a/test/sharness/t0114-gateway-subdomains.sh b/test/sharness/t0114-gateway-subdomains.sh index 93232577638..4c5f49b6351 100755 --- a/test/sharness/t0114-gateway-subdomains.sh +++ b/test/sharness/t0114-gateway-subdomains.sh @@ -403,6 +403,14 @@ test_hostname_gateway_response_should_contain \ "http://127.0.0.1:$GWAY_PORT/ipns/en.wikipedia-on-ipfs.org/wiki" \ "Location: http://en.wikipedia-on-ipfs.org.ipns.example.com/wiki" +# DNSLink on Public gateway with a single-level wildcard TLS cert +# "Option C" from https://github.com/ipfs/in-web-browsers/issues/169 +test_expect_success \ + "request for example.com/ipns/{fqdn} with X-Forwarded-Proto redirects to TLS-safe label in subdomain" " + curl -H \"Host: example.com\" -H \"X-Forwarded-Proto: https\" -sD - \"http://127.0.0.1:$GWAY_PORT/ipns/en.wikipedia-on-ipfs.org/wiki\" > response && + test_should_contain \"Location: https://en-wikipedia--on--ipfs-org.ipns.example.com/wiki\" response + " + # *.ipfs.example.com: subdomain requests made with custom FQDN in Host header test_hostname_gateway_response_should_contain \ @@ -539,14 +547,22 @@ test_hostname_gateway_response_should_contain \ "http://127.0.0.1:$GWAY_PORT" \ "$CID_VAL" +# DNSLink on Public gateway with a single-level wildcard TLS cert +# "Option C" from https://github.com/ipfs/in-web-browsers/issues/169 +test_expect_success \ + "request for {single-label-dnslink}.ipns.example.com with X-Forwarded-Proto returns expected payload" " + curl -H \"Host: dnslink--subdomain--gw--test-example-org.ipns.example.com\" -H \"X-Forwarded-Proto: https\" -sD - \"http://127.0.0.1:$GWAY_PORT\" > response && + test_should_contain \"$CID_VAL\" response + " + ## Test subdomain handling of CIDs that do not fit in a single DNS Label (>63chars) ## https://github.com/ipfs/go-ipfs/issues/7318 ## ============================================================================ # ed25519 fits under 63 char limit when represented in base36 IPNS_KEY="test_key_ed25519" -IPNS_ED25519_B58MH=$(ipfs key list -l -f b58mh | grep $IPNS_KEY | cut -d " " -f1 | tr -d "\n") -IPNS_ED25519_B36CID=$(ipfs key list -l -f b36cid | grep $IPNS_KEY | cut -d " " -f1 | tr -d "\n") +IPNS_ED25519_B58MH=$(ipfs key list -l --ipns-base b58mh | grep $IPNS_KEY | cut -d" " -f1 | tr -d "\n") +IPNS_ED25519_B36CID=$(ipfs key list -l --ipns-base base36 | grep $IPNS_KEY | cut -d" " -f1 | tr -d "\n") # sha512 will be over 63char limit, even when represented in Base36 CIDv1_TOO_LONG=$(echo $CID_VAL | ipfs add --cid-version 1 --hash sha2-512 -Q) From f31d9b1e72e3f250af719108c728c0a153f6f638 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Mon, 7 Dec 2020 18:58:42 +0100 Subject: [PATCH 076/116] fix: improved error message on broken CIDv0 Closes #7792 --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 8e3c05f59be..47f7f7f130c 100644 --- a/go.mod +++ b/go.mod @@ -51,7 +51,7 @@ require ( github.com/ipfs/go-metrics-interface v0.0.1 github.com/ipfs/go-metrics-prometheus v0.0.2 github.com/ipfs/go-mfs v0.1.2 - github.com/ipfs/go-path v0.0.8 + github.com/ipfs/go-path v0.0.9 github.com/ipfs/go-pinning-service-http-client v0.1.0 github.com/ipfs/go-unixfs v0.2.4 github.com/ipfs/go-verifcid v0.0.1 diff --git a/go.sum b/go.sum index 9e835c14042..e0fb463e371 100644 --- a/go.sum +++ b/go.sum @@ -455,8 +455,8 @@ 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-path v0.0.7 h1:H06hKMquQ0aYtHiHryOMLpQC1qC3QwXwkahcEVD51Ho= github.com/ipfs/go-path v0.0.7/go.mod h1:6KTKmeRnBXgqrTvzFrPV3CamxcgvXX/4z79tfAd2Sno= -github.com/ipfs/go-path v0.0.8 h1:R0k6t9x/pa+g8qzl5apQIPurJFozXhopks3iw3MX+jU= -github.com/ipfs/go-path v0.0.8/go.mod h1:VpDkSBKQ9EFQOUgi54Tq/O/tGi8n1RfYNks13M3DEs8= +github.com/ipfs/go-path v0.0.9 h1:BIi831cNED8YnIlIKo9y1SI3u+E+FwQQD+rIIw8PwFA= +github.com/ipfs/go-path v0.0.9/go.mod h1:VpDkSBKQ9EFQOUgi54Tq/O/tGi8n1RfYNks13M3DEs8= 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= From 88dd257ace53b56759a760ab9df189e43a7fda17 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Fri, 8 Jan 2021 00:31:46 +0100 Subject: [PATCH 077/116] test: false for isHTTPSRequest As suggested in https://github.com/ipfs/go-ipfs/pull/7847#discussion_r551933162 --- core/corehttp/hostname.go | 2 +- core/corehttp/hostname_test.go | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/core/corehttp/hostname.go b/core/corehttp/hostname.go index 7e2d07821c7..3ce1d08c26d 100644 --- a/core/corehttp/hostname.go +++ b/core/corehttp/hostname.go @@ -414,7 +414,7 @@ func toDNSLabel(rootID string, rootCID cid.Cid) (dnsCID string, err error) { } // Returns true if HTTP request involves TLS certificate. -// See https://github.com/ipfs/in-web-browsers/issues/169 to uderstand how it +// See https://github.com/ipfs/in-web-browsers/issues/169 to understand how it // impacts DNSLink websites on public gateways. func isHTTPSRequest(r *http.Request) bool { // X-Forwarded-Proto if added by a reverse proxy diff --git a/core/corehttp/hostname_test.go b/core/corehttp/hostname_test.go index f469a7720cd..3ece5e88f8f 100644 --- a/core/corehttp/hostname_test.go +++ b/core/corehttp/hostname_test.go @@ -106,6 +106,9 @@ func TestIsHTTPSRequest(t *testing.T) { httpsRequest := httptest.NewRequest("GET", "https://https-request-stub.example.com", nil) httpsProxiedRequest := httptest.NewRequest("GET", "http://proxied-https-request-stub.example.com", nil) httpsProxiedRequest.Header.Set("X-Forwarded-Proto", "https") + httpProxiedRequest := httptest.NewRequest("GET", "http://proxied-http-request-stub.example.com", nil) + httpProxiedRequest.Header.Set("X-Forwarded-Proto", "http") + oddballRequest := httptest.NewRequest("GET", "foo://127.0.0.1:8080", nil) for _, test := range []struct { in *http.Request out bool @@ -113,6 +116,8 @@ func TestIsHTTPSRequest(t *testing.T) { {httpRequest, false}, {httpsRequest, true}, {httpsProxiedRequest, true}, + {httpProxiedRequest, false}, + {oddballRequest, false}, } { out := isHTTPSRequest(test.in) if out != test.out { From 267d6fc4fe476afa819bb9cd40bf599e0bceb3e4 Mon Sep 17 00:00:00 2001 From: gammazero Date: Tue, 12 Jan 2021 14:54:21 -0800 Subject: [PATCH 078/116] Modify escaping --- core/commands/cmdenv/env.go | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/core/commands/cmdenv/env.go b/core/commands/cmdenv/env.go index 7e847525c42..5d256810931 100644 --- a/core/commands/cmdenv/env.go +++ b/core/commands/cmdenv/env.go @@ -72,13 +72,27 @@ func GetConfigRoot(env cmds.Environment) (string, error) { return ctx.ConfigRoot, nil } -// EscNonPrint converts control characters and non-printable characters into Go +// EscNonPrint converts non-printable characters and backslash into Go // escape sequences, if the given string contains any. func EscNonPrint(s string) string { + // First see if escaping is needed, to avoid creating garbage. + if !needEscape(s) { + return s + } + + esc := strconv.Quote(s) + // Remove first and last quote, and unescape quotes. + return strings.ReplaceAll(esc[1:len(esc)-1], `\"`, `"`) +} + +func needEscape(s string) bool { + if strings.ContainsRune(s, '\\') { + return true + } for _, r := range s { if !strconv.IsPrint(r) { - return strings.Trim(strconv.Quote(s), "\"") + return true } } - return s + return false } From 26c569a0bcd020f1f1efbd948d666289b86673ff Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 11 Dec 2020 11:25:09 +0000 Subject: [PATCH 079/116] chore(deps): bump github.com/ipfs/go-graphsync from 0.5.1 to 0.5.2 Bumps [github.com/ipfs/go-graphsync](https://github.com/ipfs/go-graphsync) from 0.5.1 to 0.5.2. - [Release notes](https://github.com/ipfs/go-graphsync/releases) - [Changelog](https://github.com/ipfs/go-graphsync/blob/master/CHANGELOG.md) - [Commits](https://github.com/ipfs/go-graphsync/compare/v0.5.1...v0.5.2) Signed-off-by: dependabot-preview[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 8e3c05f59be..dd9d6804b5c 100644 --- a/go.mod +++ b/go.mod @@ -28,7 +28,7 @@ require ( github.com/ipfs/go-ds-measure v0.1.0 github.com/ipfs/go-filestore v0.0.3 github.com/ipfs/go-fs-lock v0.0.6 - github.com/ipfs/go-graphsync v0.5.1 + github.com/ipfs/go-graphsync v0.5.2 github.com/ipfs/go-ipfs-blockstore v0.1.4 github.com/ipfs/go-ipfs-chunker v0.0.5 github.com/ipfs/go-ipfs-cmds v0.5.0 diff --git a/go.sum b/go.sum index 9e835c14042..bee4d4e9ac3 100644 --- a/go.sum +++ b/go.sum @@ -354,8 +354,8 @@ github.com/ipfs/go-filestore v0.0.3 h1:MhZ1jT5K3NewZwim6rS/akcJLm1xM+r6nz6foeB9E github.com/ipfs/go-filestore v0.0.3/go.mod h1:dvXRykFzyyXN2CdNlRGzDAkXMDPyI+D7JE066SiKLSE= github.com/ipfs/go-fs-lock v0.0.6 h1:sn3TWwNVQqSeNjlWy6zQ1uUGAZrV3hPOyEA6y1/N2a0= github.com/ipfs/go-fs-lock v0.0.6/go.mod h1:OTR+Rj9sHiRubJh3dRhD15Juhd/+w6VPOY28L7zESmM= -github.com/ipfs/go-graphsync v0.5.1 h1:4fXBRvRKicTgTmCFMmEua/H5jvmAOLgU9Z7PCPWt2ec= -github.com/ipfs/go-graphsync v0.5.1/go.mod h1:e2ZxnClqBBYAtd901g9vXMJzS47labjAtOzsWtOzKNk= +github.com/ipfs/go-graphsync v0.5.2 h1:USD+daaSC+7pLHCxROThSaF6SF7WYXF03sjrta0rCfA= +github.com/ipfs/go-graphsync v0.5.2/go.mod h1:e2ZxnClqBBYAtd901g9vXMJzS47labjAtOzsWtOzKNk= github.com/ipfs/go-ipfs-blockstore v0.0.1/go.mod h1:d3WClOmRQKFnJ0Jz/jj/zmksX0ma1gROTlovZKBmN08= github.com/ipfs/go-ipfs-blockstore v0.1.0 h1:V1GZorHFUIB6YgTJQdq7mcaIpUfCM3fCyVi+MTo9O88= github.com/ipfs/go-ipfs-blockstore v0.1.0/go.mod h1:5aD0AvHPi7mZc6Ci1WCAhiBQu2IsfTduLl+422H6Rqw= From 20132a83eff4e6acccb78f2ca53bf152e8b56a7e Mon Sep 17 00:00:00 2001 From: gammazero Date: Thu, 14 Jan 2021 02:29:11 -0800 Subject: [PATCH 080/116] code review changes --- core/commands/cmdenv/env.go | 7 +++-- core/commands/cmdenv/env_test.go | 48 ++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 core/commands/cmdenv/env_test.go diff --git a/core/commands/cmdenv/env.go b/core/commands/cmdenv/env.go index 5d256810931..c21612c3305 100644 --- a/core/commands/cmdenv/env.go +++ b/core/commands/cmdenv/env.go @@ -72,10 +72,11 @@ func GetConfigRoot(env cmds.Environment) (string, error) { return ctx.ConfigRoot, nil } -// EscNonPrint converts non-printable characters and backslash into Go -// escape sequences, if the given string contains any. +// EscNonPrint converts non-printable characters and backslash into Go escape +// sequences. This is done to display all characters in a string, including +// those that would otherwise not be displayed or have an undesirable effect on +// the display. func EscNonPrint(s string) string { - // First see if escaping is needed, to avoid creating garbage. if !needEscape(s) { return s } diff --git a/core/commands/cmdenv/env_test.go b/core/commands/cmdenv/env_test.go new file mode 100644 index 00000000000..1e02851870d --- /dev/null +++ b/core/commands/cmdenv/env_test.go @@ -0,0 +1,48 @@ +package cmdenv + +import ( + "strconv" + "testing" +) + +func TestEscNonPrint(t *testing.T) { + b := []byte("hello") + b[2] = 0x7f + s := string(b) + if !needEscape(s) { + t.Fatal("string needs escaping") + } + if !hasNonPrintable(s) { + t.Fatal("expected non-printable") + } + if hasNonPrintable(EscNonPrint(s)) { + t.Fatal("escaped string has non-printable") + } + if EscNonPrint(`hel\lo`) != `hel\\lo` { + t.Fatal("backslash not escaped") + } + + s = `hello` + if needEscape(s) { + t.Fatal("string does not need escaping") + } + if EscNonPrint(s) != s { + t.Fatal("string should not have changed") + } + s = `"hello"` + if EscNonPrint(s) != s { + t.Fatal("string should not have changed") + } + if EscNonPrint(`"hel\"lo"`) != `"hel\\"lo"` { + t.Fatal("did not get expected escaped string") + } +} + +func hasNonPrintable(s string) bool { + for _, r := range s { + if !strconv.IsPrint(r) { + return true + } + } + return false +} From f932510b88a08bb674e4191431b3d33a7b3ec690 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Thu, 14 Jan 2021 20:14:35 +0100 Subject: [PATCH 081/116] fix: check if rootID has DNSLink before uninlining This kinda enables to run their custom DNS resolver with custom tlds/names that are independent from the public DNS network. --- core/corehttp/hostname.go | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/core/corehttp/hostname.go b/core/corehttp/hostname.go index 3ce1d08c26d..da133f7abe1 100644 --- a/core/corehttp/hostname.go +++ b/core/corehttp/hostname.go @@ -209,11 +209,14 @@ func HostnameOption() ServeOption { // TLS cert if represented as a single DNS label: // https://my-v--long-example-com.ipns.dweb.link if ns == "ipns" && !strings.Contains(rootID, ".") { - // my-v--long-example-com → my.v-long.example.com - dnslinkFQDN := toDNSLinkFQDN(rootID) - if isDNSLinkName(r.Context(), coreAPI, dnslinkFQDN) { - // update path prefix to use real FQDN with DNSLink - pathPrefix = "/ipns/" + dnslinkFQDN + // if there is no TXT recordfor rootID + if !isDNSLinkName(r.Context(), coreAPI, rootID) { + // my-v--long-example-com → my.v-long.example.com + dnslinkFQDN := toDNSLinkFQDN(rootID) + if isDNSLinkName(r.Context(), coreAPI, dnslinkFQDN) { + // update path prefix to use real FQDN with DNSLink + pathPrefix = "/ipns/" + dnslinkFQDN + } } } } From 36368ee4ddfb8943d96f2e34b3283d11a1498ff6 Mon Sep 17 00:00:00 2001 From: Dennis Trautwein Date: Sat, 5 Dec 2020 17:02:40 +0100 Subject: [PATCH 082/116] feat: support requests from registerProtocolHandler This commit adds support for requests produced by navigator.registerProtocolHandler on gateways. Now one can register `dweb.link` as an URI handler for `ipfs://`: ``` navigator.registerProtocolHandler('ipfs', 'https://dweb.link/ipfs/?uri=%s', 'ipfs resolver') ``` Then opening `ipfs://QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR` will produce an HTTP GET call to: ``` https://dweb.link/ipfs?uri=ipfs%3A%2F%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR ``` The query parameter `uri` will now be parsed and the given content identifier resolved via: `https://dweb.link/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR` --- core/corehttp/gateway_handler.go | 17 +++++++++++++ core/corehttp/gateway_test.go | 41 ++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/core/corehttp/gateway_handler.go b/core/corehttp/gateway_handler.go index b78bacb02e5..8c34ba4541e 100644 --- a/core/corehttp/gateway_handler.go +++ b/core/corehttp/gateway_handler.go @@ -181,6 +181,23 @@ func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request } originalUrlPath := prefix + requestURI.Path + // Query parameter handling to support requests produced by navigator.registerProtocolHandler. + // E.g. This code will redirect calls to /ipfs/?uri=ipfs%3A%2F%2Fcontent-identifier + // to /ipfs/content-identifier. + if uri := r.URL.Query().Get("uri"); uri != "" { + u, err := url.Parse(uri) + 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 + } + http.Redirect(w, r, gopath.Join("/", prefix, u.Scheme, u.Host), http.StatusMovedPermanently) + return + } + // Service Worker registration request if r.Header.Get("Service-Worker") == "script" { // Disallow Service Worker registration on namespace roots diff --git a/core/corehttp/gateway_test.go b/core/corehttp/gateway_test.go index f98b4a7737b..049ccd27c4c 100644 --- a/core/corehttp/gateway_test.go +++ b/core/corehttp/gateway_test.go @@ -161,6 +161,47 @@ func matchPathOrBreadcrumbs(s string, expected string) bool { return matched } +func TestUriQueryRedirect(t *testing.T) { + ts, _, _ := newTestServerAndNode(t, mockNamesys{}) + + cid := "QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR" + for i, test := range []struct { + path string + status int + location string + }{ + {"/ipfs/?uri=ipfs://" + cid, http.StatusMovedPermanently, "/ipfs/" + cid}, + {"/ipfs/?uri=ipfs%3A%2F%2F" + cid, http.StatusMovedPermanently, "/ipfs/" + cid}, + {"/ipfs?uri=ipfs://" + cid, http.StatusMovedPermanently, "/ipfs/?uri=ipfs://" + cid}, + {"/ipfs/?uri=ipns://" + cid, http.StatusMovedPermanently, "/ipns/" + cid}, + {"/ipns?uri=ipns://" + cid, http.StatusMovedPermanently, "/ipns/?uri=ipns://" + cid}, + {"/ipns/?uri=ipfs://" + cid, http.StatusMovedPermanently, "/ipfs/" + cid}, + {"/ipns/?uri=ipfs://" + cid, http.StatusMovedPermanently, "/ipfs/" + cid}, + {"/ipfs/?uri=unsupported://" + cid, http.StatusBadRequest, ""}, + {"/ipfs/?uri=" + cid, http.StatusBadRequest, ""}, + } { + + r, err := http.NewRequest(http.MethodGet, ts.URL+test.path, nil) + if err != nil { + t.Fatal(err) + } + resp, err := doWithoutRedirect(r) + if err != nil { + t.Fatal(err) + } + defer resp.Body.Close() + + if resp.StatusCode != test.status { + t.Errorf("(%d) got %d, expected %d from %s", i, resp.StatusCode, test.status, ts.URL+test.path) + } + + locHdr := resp.Header.Get("Location") + if locHdr != test.location { + t.Errorf("(%d) location header got %s, expected %s from %s", i, locHdr, test.location, ts.URL+test.path) + } + } +} + func TestGatewayGet(t *testing.T) { ns := mockNamesys{} ts, api, ctx := newTestServerAndNode(t, ns) From 3de5b14e0c248ab1f611215836ace4e134a25b61 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Sat, 12 Dec 2020 02:43:16 +0100 Subject: [PATCH 083/116] fix: ?uri= url-decode and preserve query This makes ?uri= param able to process URIs passed by web browsers https://developer.mozilla.org/en-US/docs/Web/API/Navigator/registerProtocolHandler --- core/corehttp/gateway_handler.go | 21 ++++++++++++++++----- core/corehttp/gateway_test.go | 10 ++++++++-- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/core/corehttp/gateway_handler.go b/core/corehttp/gateway_handler.go index 8c34ba4541e..2ef4fefb1b8 100644 --- a/core/corehttp/gateway_handler.go +++ b/core/corehttp/gateway_handler.go @@ -181,10 +181,17 @@ func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request } originalUrlPath := prefix + requestURI.Path - // Query parameter handling to support requests produced by navigator.registerProtocolHandler. - // E.g. This code will redirect calls to /ipfs/?uri=ipfs%3A%2F%2Fcontent-identifier - // to /ipfs/content-identifier. - if uri := r.URL.Query().Get("uri"); uri != "" { + // ?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 != "" { + // Browsers will pass URI in URL-escaped form, we need to unescape it first + uri, err := url.QueryUnescape(uriParam) + if err != nil { + webError(w, "failed to unescape uri query parameter", err, http.StatusBadRequest) + return + } u, err := url.Parse(uri) if err != nil { webError(w, "failed to parse uri query parameter", err, http.StatusBadRequest) @@ -194,7 +201,11 @@ func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request webError(w, "uri query parameter scheme must be ipfs or ipns", err, http.StatusBadRequest) return } - http.Redirect(w, r, gopath.Join("/", prefix, u.Scheme, u.Host), http.StatusMovedPermanently) + 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) return } diff --git a/core/corehttp/gateway_test.go b/core/corehttp/gateway_test.go index 049ccd27c4c..d4fcf5a3825 100644 --- a/core/corehttp/gateway_test.go +++ b/core/corehttp/gateway_test.go @@ -170,12 +170,18 @@ func TestUriQueryRedirect(t *testing.T) { status int location string }{ + // - Browsers will send original URI in URL-escaped form + // - We expect query parameters to be persisted + // - We drop fragments, as those should not be sent by a browser + {"/ipfs/?uri=ipfs%3A%2F%2FQmXoypizjW3WknFiJnKLwHCnL72vedxjQkDDP1mXWo6uco%2Fwiki%2FFoo_%C4%85%C4%99.html%3Ffilename%3Dtest-%C4%99.html%23header-%C4%85", http.StatusMovedPermanently, "/ipfs/QmXoypizjW3WknFiJnKLwHCnL72vedxjQkDDP1mXWo6uco/wiki/Foo_%c4%85%c4%99.html?filename=test-%c4%99.html"}, + {"/ipfs/?uri=ipns%3A%2F%2Fexample.com%2Fwiki%2FFoo_%C4%85%C4%99.html%3Ffilename%3Dtest-%C4%99.html", http.StatusMovedPermanently, "/ipns/example.com/wiki/Foo_%c4%85%c4%99.html?filename=test-%c4%99.html"}, {"/ipfs/?uri=ipfs://" + cid, http.StatusMovedPermanently, "/ipfs/" + cid}, - {"/ipfs/?uri=ipfs%3A%2F%2F" + cid, http.StatusMovedPermanently, "/ipfs/" + cid}, {"/ipfs?uri=ipfs://" + cid, http.StatusMovedPermanently, "/ipfs/?uri=ipfs://" + cid}, {"/ipfs/?uri=ipns://" + cid, http.StatusMovedPermanently, "/ipns/" + cid}, + {"/ipns/?uri=ipfs%3A%2F%2FQmXoypizjW3WknFiJnKLwHCnL72vedxjQkDDP1mXWo6uco%2Fwiki%2FFoo_%C4%85%C4%99.html%3Ffilename%3Dtest-%C4%99.html%23header-%C4%85", http.StatusMovedPermanently, "/ipfs/QmXoypizjW3WknFiJnKLwHCnL72vedxjQkDDP1mXWo6uco/wiki/Foo_%c4%85%c4%99.html?filename=test-%c4%99.html"}, + {"/ipns/?uri=ipns%3A%2F%2Fexample.com%2Fwiki%2FFoo_%C4%85%C4%99.html%3Ffilename%3Dtest-%C4%99.html", http.StatusMovedPermanently, "/ipns/example.com/wiki/Foo_%c4%85%c4%99.html?filename=test-%c4%99.html"}, {"/ipns?uri=ipns://" + cid, http.StatusMovedPermanently, "/ipns/?uri=ipns://" + cid}, - {"/ipns/?uri=ipfs://" + cid, http.StatusMovedPermanently, "/ipfs/" + cid}, + {"/ipns/?uri=ipns://" + cid, http.StatusMovedPermanently, "/ipns/" + cid}, {"/ipns/?uri=ipfs://" + cid, http.StatusMovedPermanently, "/ipfs/" + cid}, {"/ipfs/?uri=unsupported://" + cid, http.StatusBadRequest, ""}, {"/ipfs/?uri=" + cid, http.StatusBadRequest, ""}, From abb25a1cfc202ab4427bb1d3fa0c16d6e2700bd5 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Sat, 12 Dec 2020 12:28:42 +0100 Subject: [PATCH 084/116] refactor: remove redundant urlescape URL.Query() will already decode the query parameters --- core/corehttp/gateway_handler.go | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/core/corehttp/gateway_handler.go b/core/corehttp/gateway_handler.go index 2ef4fefb1b8..e4719817418 100644 --- a/core/corehttp/gateway_handler.go +++ b/core/corehttp/gateway_handler.go @@ -186,13 +186,7 @@ func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request // 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 != "" { - // Browsers will pass URI in URL-escaped form, we need to unescape it first - uri, err := url.QueryUnescape(uriParam) - if err != nil { - webError(w, "failed to unescape uri query parameter", err, http.StatusBadRequest) - return - } - u, err := url.Parse(uri) + u, err := url.Parse(uriParam) if err != nil { webError(w, "failed to parse uri query parameter", err, http.StatusBadRequest) return From cdad39479cb0f08e8a9c15be0009427b63c7e73f Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Wed, 13 Jan 2021 16:41:38 +0100 Subject: [PATCH 085/116] test: sharness for ?uri= router Additional tests to ensure there are no regressions, as this will be used by browser vendors in the future. --- test/sharness/t0114-gateway-subdomains.sh | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/test/sharness/t0114-gateway-subdomains.sh b/test/sharness/t0114-gateway-subdomains.sh index 4c5f49b6351..b9af0805e57 100755 --- a/test/sharness/t0114-gateway-subdomains.sh +++ b/test/sharness/t0114-gateway-subdomains.sh @@ -379,7 +379,12 @@ test_expect_success "request for http://example.com/ipfs/{CID} with X-Forwarded- test_should_contain \"Location: https://$CIDv1.ipfs.example.com/\" response " - +# Support ipfs:// in https://developer.mozilla.org/en-US/docs/Web/API/Navigator/registerProtocolHandler +test_hostname_gateway_response_should_contain \ + "request for example.com/ipfs/?uri=ipfs%3A%2F%2F.. produces redirect to /ipfs/.. content path" \ + "example.com" \ + "http://127.0.0.1:$GWAY_PORT/ipfs/?uri=ipfs%3A%2F%2FQmXoypizjW3WknFiJnKLwHCnL72vedxjQkDDP1mXWo6uco%2Fwiki%2FDiego_Maradona.html" \ + "Location: /ipfs/QmXoypizjW3WknFiJnKLwHCnL72vedxjQkDDP1mXWo6uco/wiki/Diego_Maradona.html" # example.com/ipns/ @@ -411,6 +416,13 @@ test_expect_success \ test_should_contain \"Location: https://en-wikipedia--on--ipfs-org.ipns.example.com/wiki\" response " +# Support ipns:// in https://developer.mozilla.org/en-US/docs/Web/API/Navigator/registerProtocolHandler +test_hostname_gateway_response_should_contain \ + "request for example.com/ipns/?uri=ipns%3A%2F%2F.. produces redirect to /ipns/.. content path" \ + "example.com" \ + "http://127.0.0.1:$GWAY_PORT/ipns/?uri=ipns%3A%2F%2Fen.wikipedia-on-ipfs.org" \ + "Location: /ipns/en.wikipedia-on-ipfs.org" + # *.ipfs.example.com: subdomain requests made with custom FQDN in Host header test_hostname_gateway_response_should_contain \ From a0f90d3a140a4616c5930bcb8c62445717ccc857 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Thu, 14 Jan 2021 20:51:02 +0100 Subject: [PATCH 086/116] test: cover 2 remaining lines --- core/corehttp/gateway_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/core/corehttp/gateway_test.go b/core/corehttp/gateway_test.go index d4fcf5a3825..a05e456ab6c 100644 --- a/core/corehttp/gateway_test.go +++ b/core/corehttp/gateway_test.go @@ -184,6 +184,7 @@ func TestUriQueryRedirect(t *testing.T) { {"/ipns/?uri=ipns://" + cid, http.StatusMovedPermanently, "/ipns/" + cid}, {"/ipns/?uri=ipfs://" + cid, http.StatusMovedPermanently, "/ipfs/" + cid}, {"/ipfs/?uri=unsupported://" + cid, http.StatusBadRequest, ""}, + {"/ipfs/?uri=invaliduri", http.StatusBadRequest, ""}, {"/ipfs/?uri=" + cid, http.StatusBadRequest, ""}, } { From 216b858f8a7492f38e7141b26285d06ecbc65108 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Thu, 14 Jan 2021 21:07:23 +0100 Subject: [PATCH 087/116] test: JSON response on empty remote service ls --- test/sharness/t0700-remotepin.sh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/sharness/t0700-remotepin.sh b/test/sharness/t0700-remotepin.sh index a033f87457f..b03d4177d5b 100755 --- a/test/sharness/t0700-remotepin.sh +++ b/test/sharness/t0700-remotepin.sh @@ -20,6 +20,14 @@ TEST_PIN_SVC_KEY=$(curl -s -X POST "$TEST_PIN_SVC/users" -d email="go-ipfs-sharn # pin remote service add|ls|rm +# confirm empty service list response has proper json struct +# https://github.com/ipfs/go-ipfs/pull/7829 +test_expect_success "test 'ipfs pin remote service ls' JSON on empty list" ' + ipfs pin remote service ls --stat --enc=json | tee empty_ls_out && + echo "{\"RemoteServices\":[]}" > exp_ls_out && + test_cmp exp_ls_out empty_ls_out +' + # add valid and invalid services test_expect_success "creating test user on remote pinning service" ' echo CI host IP address ${TEST_PIN_SVC} && From a95a86ed54d6498f6d47232da1cbd111eebbd659 Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Thu, 14 Jan 2021 19:13:06 -0500 Subject: [PATCH 088/116] feat: ipfs pin remote ls commands are comma delimited on the CLI only --- core/commands/pin/remotepin.go | 24 ++++++++---------------- go.mod | 3 +-- go.sum | 6 ++---- 3 files changed, 11 insertions(+), 22 deletions(-) diff --git a/core/commands/pin/remotepin.go b/core/commands/pin/remotepin.go index d930adb0a3b..1ac31acc20a 100644 --- a/core/commands/pin/remotepin.go +++ b/core/commands/pin/remotepin.go @@ -224,8 +224,8 @@ Returns a list of objects that are pinned to a remote pinning service. Arguments: []cmds.Argument{}, Options: []cmds.Option{ cmds.StringOption(pinNameOptionName, "Return pins objects with names that contain provided value (case-sensitive, exact match)."), - cmds.StringsOption(pinCIDsOptionName, "Return only pin objects for the specified CID(s); optional, comma separated."), - cmds.StringsOption(pinStatusOptionName, "Return only pin objects with the specified statuses (queued,pinning,pinned,failed)").WithDefault([]string{"pinned"}), + cmds.DelimitedStringsOption(",", pinCIDsOptionName, "Return only pin objects for the specified CID(s); optional, comma separated."), + cmds.DelimitedStringsOption(",", pinStatusOptionName, "Return only pin objects with the specified statuses (queued,pinning,pinned,failed)").WithDefault([]string{"pinned"}), pinServiceNameOption, }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { @@ -270,8 +270,8 @@ func lsRemote(ctx context.Context, req *cmds.Request, c *pinclient.Client) (chan if cidsRaw, cidsFound := req.Options[pinCIDsOptionName]; cidsFound { cidsRawArr := cidsRaw.([]string) - parsedCIDs := []cid.Cid{} - for _, rawCID := range flattenCommaList(cidsRawArr) { + var parsedCIDs []cid.Cid + for _, rawCID := range cidsRawArr { parsedCID, err := cid.Decode(rawCID) if err != nil { return nil, nil, fmt.Errorf("CID %q cannot be parsed: %v", rawCID, err) @@ -282,8 +282,8 @@ func lsRemote(ctx context.Context, req *cmds.Request, c *pinclient.Client) (chan } if statusRaw, statusFound := req.Options[pinStatusOptionName]; statusFound { statusRawArr := statusRaw.([]string) - parsedStatuses := []pinclient.Status{} - for _, rawStatus := range flattenCommaList(statusRawArr) { + var parsedStatuses []pinclient.Status + for _, rawStatus := range statusRawArr { s := pinclient.Status(rawStatus) if s.String() == string(pinclient.StatusUnknown) { return nil, nil, fmt.Errorf("status %q is not valid", rawStatus) @@ -298,14 +298,6 @@ func lsRemote(ctx context.Context, req *cmds.Request, c *pinclient.Client) (chan return psCh, errCh, nil } -func flattenCommaList(list []string) []string { - flatList := list[:0] - for _, s := range list { - flatList = append(flatList, strings.Split(s, ",")...) - } - return flatList -} - var rmRemotePinCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Remove pinned objects from remote pinning service.", @@ -319,8 +311,8 @@ collected if needed. Options: []cmds.Option{ pinServiceNameOption, cmds.StringOption(pinNameOptionName, "Remove pin objects with names that contain provided value (case-sensitive, exact match)."), - cmds.StringsOption(pinCIDsOptionName, "Remove only pin objects for the specified CID(s)."), - cmds.StringsOption(pinStatusOptionName, "Remove only pin objects with the specified statuses (queued,pinning,pinned,failed).").WithDefault([]string{"pinned"}), + cmds.DelimitedStringsOption(",", pinCIDsOptionName, "Remove only pin objects for the specified CID(s)."), + cmds.DelimitedStringsOption(",", pinStatusOptionName, "Remove only pin objects with the specified statuses (queued,pinning,pinned,failed).").WithDefault([]string{"pinned"}), cmds.BoolOption(pinForceOptionName, "Remove multiple pins without confirmation.").WithDefault(false), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { diff --git a/go.mod b/go.mod index e9c80157e12..531cb258875 100644 --- a/go.mod +++ b/go.mod @@ -31,7 +31,7 @@ require ( github.com/ipfs/go-graphsync v0.5.1 github.com/ipfs/go-ipfs-blockstore v0.1.4 github.com/ipfs/go-ipfs-chunker v0.0.5 - github.com/ipfs/go-ipfs-cmds v0.5.0 + github.com/ipfs/go-ipfs-cmds v0.6.0 github.com/ipfs/go-ipfs-config v0.11.0 github.com/ipfs/go-ipfs-ds-help v0.1.1 github.com/ipfs/go-ipfs-exchange-interface v0.0.1 @@ -57,7 +57,6 @@ require ( github.com/ipfs/go-verifcid v0.0.1 github.com/ipfs/interface-go-ipfs-core v0.4.0 github.com/ipld/go-car v0.1.1-0.20201015032735-ff6ccdc46acc - github.com/jbenet/go-fuse-version v0.0.0-20160322195114-6d4c97bcf253 // indirect github.com/jbenet/go-is-domain v1.0.5 github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c github.com/jbenet/go-temp-err-catcher v0.1.0 diff --git a/go.sum b/go.sum index 9891a126673..8d74d6afbe3 100644 --- a/go.sum +++ b/go.sum @@ -327,8 +327,8 @@ github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtL 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.5.0 h1:T1ZT6Qu3IUCp6FgU2IzVtvGLaexEWo9q13+S5ic+Q5Y= -github.com/ipfs/go-ipfs-cmds v0.5.0/go.mod h1:ZgYiWVnCk43ChwoH8hAmI1IRbuVtq3GSTHwtRB/Kqhk= +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.11.0 h1:w4t2pz415Gtg6MTUKAq06C7ezC59/Us+k3+n1Tje+wg= github.com/ipfs/go-ipfs-config v0.11.0/go.mod h1:Ei/FLgHGTdPyqCPK0oPCwGTe8VSnsjJjx7HZqUb6Ry0= github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= @@ -429,8 +429,6 @@ github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+ 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-fuse-version v0.0.0-20160322195114-6d4c97bcf253 h1:+AUuGGAh/2X3wcomiZvjeTcx5OvGXsfdnIqk3KPM+HE= -github.com/jbenet/go-fuse-version v0.0.0-20160322195114-6d4c97bcf253/go.mod h1:gWtF+3u3zVe5/+I44niTEcU/KmVo2oMyLh0WhxpBT28= github.com/jbenet/go-is-domain v1.0.5 h1:r92uiHbMEJo9Fkey5pMBtZAzjPQWic0ieo7Jw1jEuQQ= github.com/jbenet/go-is-domain v1.0.5/go.mod h1:xbRLRb0S7FgzDBTJlguhDVwLYM/5yNtvktxj2Ttfy7Q= github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c h1:uUx61FiAa1GI6ZmVd2wf2vULeQZIKG66eybjNXKYCz4= From 1e260f2f9dbd9eb6e2ad0d8b03285f84617c04e2 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 27 Jan 2021 18:45:09 +0000 Subject: [PATCH 089/116] chore(deps): bump github.com/libp2p/go-libp2p-pubsub from 0.4.0 to 0.4.1 Bumps [github.com/libp2p/go-libp2p-pubsub](https://github.com/libp2p/go-libp2p-pubsub) from 0.4.0 to 0.4.1. - [Release notes](https://github.com/libp2p/go-libp2p-pubsub/releases) - [Commits](https://github.com/libp2p/go-libp2p-pubsub/compare/v0.4.0...v0.4.1) Signed-off-by: dependabot-preview[bot] --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index aa9e7d929d7..bcff506c151 100644 --- a/go.mod +++ b/go.mod @@ -73,7 +73,7 @@ require ( github.com/libp2p/go-libp2p-mplex v0.4.1 github.com/libp2p/go-libp2p-noise v0.1.2 github.com/libp2p/go-libp2p-peerstore v0.2.6 - github.com/libp2p/go-libp2p-pubsub v0.4.0 + github.com/libp2p/go-libp2p-pubsub v0.4.1 github.com/libp2p/go-libp2p-pubsub-router v0.4.0 github.com/libp2p/go-libp2p-quic-transport v0.10.0 github.com/libp2p/go-libp2p-record v0.1.3 diff --git a/go.sum b/go.sum index 2b2f83faa27..10df163589c 100644 --- a/go.sum +++ b/go.sum @@ -617,6 +617,8 @@ github.com/libp2p/go-libp2p-protocol v0.0.1/go.mod h1:Af9n4PiruirSDjHycM1QuiMi/1 github.com/libp2p/go-libp2p-protocol v0.1.0/go.mod h1:KQPHpAabB57XQxGrXCNvbL6UEXfQqUgC/1adR2Xtflk= github.com/libp2p/go-libp2p-pubsub v0.4.0 h1:YNVRyXqBgv9i4RG88jzoTtkSOaSB45CqHkL29NNBZb4= github.com/libp2p/go-libp2p-pubsub v0.4.0/go.mod h1:izkeMLvz6Ht8yAISXjx60XUQZMq9ZMe5h2ih4dLIBIQ= +github.com/libp2p/go-libp2p-pubsub v0.4.1 h1:j4umIg5nyus+sqNfU+FWvb9aeYFQH/A+nDFhWj+8yy8= +github.com/libp2p/go-libp2p-pubsub v0.4.1/go.mod h1:izkeMLvz6Ht8yAISXjx60XUQZMq9ZMe5h2ih4dLIBIQ= 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-quic-transport v0.10.0 h1:koDCbWD9CCHwcHZL3/WEvP2A+e/o5/W5L3QS/2SPMA0= From d2442956a4315a47dd839f44b90ab150168bfbb7 Mon Sep 17 00:00:00 2001 From: gammazero Date: Wed, 27 Jan 2021 11:57:01 -0800 Subject: [PATCH 090/116] Update deps to latest pinner --- go.mod | 3 +-- go.sum | 6 ++---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index e9c80157e12..a78433e5f7a 100644 --- a/go.mod +++ b/go.mod @@ -37,7 +37,7 @@ require ( github.com/ipfs/go-ipfs-exchange-interface v0.0.1 github.com/ipfs/go-ipfs-exchange-offline v0.0.1 github.com/ipfs/go-ipfs-files v0.0.8 - github.com/ipfs/go-ipfs-pinner v0.1.0 + github.com/ipfs/go-ipfs-pinner v0.1.1 github.com/ipfs/go-ipfs-posinfo v0.0.1 github.com/ipfs/go-ipfs-provider v0.4.3 github.com/ipfs/go-ipfs-routing v0.1.0 @@ -57,7 +57,6 @@ require ( github.com/ipfs/go-verifcid v0.0.1 github.com/ipfs/interface-go-ipfs-core v0.4.0 github.com/ipld/go-car v0.1.1-0.20201015032735-ff6ccdc46acc - github.com/jbenet/go-fuse-version v0.0.0-20160322195114-6d4c97bcf253 // indirect github.com/jbenet/go-is-domain v1.0.5 github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c github.com/jbenet/go-temp-err-catcher v0.1.0 diff --git a/go.sum b/go.sum index 9891a126673..0abb4752772 100644 --- a/go.sum +++ b/go.sum @@ -344,8 +344,8 @@ github.com/ipfs/go-ipfs-exchange-offline v0.0.1/go.mod h1:WhHSFCVYX36H/anEKQboAz 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= -github.com/ipfs/go-ipfs-pinner v0.1.0 h1:rjSrbUDYd1YYHZ5dOgu+QEOuLcU0m/2a/brcxC/ReeU= -github.com/ipfs/go-ipfs-pinner v0.1.0/go.mod h1:EzyyaWCWeZJ/he9cDBH6QrEkSuRqTRWMmCoyNkylTTg= +github.com/ipfs/go-ipfs-pinner v0.1.1 h1:iJd1gwILGQJSZhhI0jn6yFOLg34Ua7fdKcB6mXp6k/M= +github.com/ipfs/go-ipfs-pinner v0.1.1/go.mod h1:EzyyaWCWeZJ/he9cDBH6QrEkSuRqTRWMmCoyNkylTTg= 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= @@ -429,8 +429,6 @@ github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+ 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-fuse-version v0.0.0-20160322195114-6d4c97bcf253 h1:+AUuGGAh/2X3wcomiZvjeTcx5OvGXsfdnIqk3KPM+HE= -github.com/jbenet/go-fuse-version v0.0.0-20160322195114-6d4c97bcf253/go.mod h1:gWtF+3u3zVe5/+I44niTEcU/KmVo2oMyLh0WhxpBT28= github.com/jbenet/go-is-domain v1.0.5 h1:r92uiHbMEJo9Fkey5pMBtZAzjPQWic0ieo7Jw1jEuQQ= github.com/jbenet/go-is-domain v1.0.5/go.mod h1:xbRLRb0S7FgzDBTJlguhDVwLYM/5yNtvktxj2Ttfy7Q= github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c h1:uUx61FiAa1GI6ZmVd2wf2vULeQZIKG66eybjNXKYCz4= From 3b82dd8e55e5e984c44a182d1aaa42d86e61d298 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Fri, 11 Dec 2020 14:43:35 +0100 Subject: [PATCH 091/116] docs: CLI docs for pin remote commands This adds docs in form of longer description that is displayed when --help is passes on the CLI. While at it, unified some language to match fields in the config file and other places + included some tips and best practices which should improve onboarding experience. --- core/commands/pin/remotepin.go | 112 +++++++++++++++++++++++++++------ 1 file changed, 92 insertions(+), 20 deletions(-) diff --git a/core/commands/pin/remotepin.go b/core/commands/pin/remotepin.go index 1ac31acc20a..b87a4251f33 100644 --- a/core/commands/pin/remotepin.go +++ b/core/commands/pin/remotepin.go @@ -56,7 +56,7 @@ const pinNameOptionName = "name" const pinCIDsOptionName = "cid" const pinStatusOptionName = "status" const pinServiceNameOptionName = "service" -const pinServiceURLOptionName = "url" +const pinServiceEndpointOptionName = "endpoint" const pinServiceKeyOptionName = "key" const pinServiceStatOptionName = "stat" const pinBackgroundOptionName = "background" @@ -89,20 +89,41 @@ func printRemotePinDetails(w io.Writer, out *RemotePinOutput) { // remote pin commands -var pinServiceNameOption = cmds.StringOption(pinServiceNameOptionName, "Name of the remote pinning service to use.") +var pinServiceNameOption = cmds.StringOption(pinServiceNameOptionName, "Name of the remote pinning service to use (mandatory).") var addRemotePinCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Pin object to remote pinning service.", - ShortDescription: "Stores an IPFS object from a given path to a remote pinning service.", + ShortDescription: "Asks remote pinning service to pin an IPFS object from a given path.", + LongDescription: ` +Asks remote pinning service to pin an IPFS object from a given path or a CID. + +To pin CID 'bafkqaaa' to service named 'mysrv' under a pin named 'mypin': + + $ ipfs pin remote add --service=mysrv --name=mypin bafkqaaa + +The above command will block until remote service returns 'pinned' status, +which may take time depending on the size and available providers of the pinned +data. + +If you prefer to not wait for pinning confirmation and return immediatelly +after remote service confirms 'queued' status, add the '--background' flag: + + $ ipfs pin remote add --service=mysrv --name=mypin --background bafkqaaa + +Status of background pin requests can be inspected with the 'ls' command: + + $ ipfs pin remote ls --service=mysrv --cid=bafkqaaa --status=queued,pinning,pinned,failed + +`, }, Arguments: []cmds.Argument{ - cmds.StringArg("ipfs-path", true, false, "Path to object(s) to be pinned."), + cmds.StringArg("ipfs-path-or-cid", true, false, "Path to object(s) to be pinned."), }, Options: []cmds.Option{ - cmds.StringOption(pinNameOptionName, "An optional name for the pin."), pinServiceNameOption, + cmds.StringOption(pinNameOptionName, "An optional name for the pin."), cmds.BoolOption(pinBackgroundOptionName, "Add to the queue on the remote service and return immediately (does not wait for pinned status).").WithDefault(false), }, Type: RemotePinOutput{}, @@ -218,15 +239,18 @@ Returns a list of objects that are pinned to a remote pinning service. `, LongDescription: ` Returns a list of objects that are pinned to a remote pinning service. + +NOTE: by default it will only show matching objects in 'pinned' state. +Pass '--status=queued,pinning,pinned,failed' to list pins in all states. `, }, Arguments: []cmds.Argument{}, Options: []cmds.Option{ - cmds.StringOption(pinNameOptionName, "Return pins objects with names that contain provided value (case-sensitive, exact match)."), - cmds.DelimitedStringsOption(",", pinCIDsOptionName, "Return only pin objects for the specified CID(s); optional, comma separated."), - cmds.DelimitedStringsOption(",", pinStatusOptionName, "Return only pin objects with the specified statuses (queued,pinning,pinned,failed)").WithDefault([]string{"pinned"}), pinServiceNameOption, + cmds.StringOption(pinNameOptionName, "Return pins with names that contain provided value (case-sensitive, exact match)."), + cmds.DelimitedStringsOption(",", pinCIDsOptionName, "Return pins for the specified CIDs (comma separated)."), + cmds.DelimitedStringsOption(",", pinStatusOptionName, "Return pins with the specified statuses (queued,pinning,pinned,failed).").WithDefault([]string{"pinned"}), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { ctx, cancel := context.WithCancel(req.Context) @@ -300,20 +324,41 @@ func lsRemote(ctx context.Context, req *cmds.Request, c *pinclient.Client) (chan var rmRemotePinCmd = &cmds.Command{ Helptext: cmds.HelpText{ - Tagline: "Remove pinned objects from remote pinning service.", - ShortDescription: ` -Removes the pin from the given object allowing it to be garbage -collected if needed. + Tagline: "Remove pins from remote pinning service.", + ShortDescription: "Removes the remote pin allowing it to be garbage collected if needed.", + LongDescription: ` +Removes remote pins allowing them to be garbage collected if needed. + +This command accepts the same search query parameters as 'ls' and it is a good +practice to execute 'ls' before 'rm' to confirm the list of pins to be removed. + +To remove a single pin for a specific CID: + + $ ipfs pin remote ls --service=mysrv --cid=bafkqaaa + $ ipfs pin remote rm --service=mysrv --cid=bafkqaaa + +When more than one pin is matching the query on the remote service an error is +returned. To confirm removal of multiple pins pass '--force': + + $ ipfs pin remote ls --service=mysrv --name=popular-name + $ ipfs pin remote rm --service=mysrv --name=popular-name --force + +NOTE: When no '--status' is passed, implicit '--status=pinned' is used. +To list and then remove all pending pin requests pass an explicit status list: + + $ ipfs pin remote ls --service=mysrv --status=queued,pinning,failed + $ ipfs pin remote rm --service=mysrv --status=queued,pinning,failed --force + `, }, Arguments: []cmds.Argument{}, Options: []cmds.Option{ pinServiceNameOption, - cmds.StringOption(pinNameOptionName, "Remove pin objects with names that contain provided value (case-sensitive, exact match)."), - cmds.DelimitedStringsOption(",", pinCIDsOptionName, "Remove only pin objects for the specified CID(s)."), - cmds.DelimitedStringsOption(",", pinStatusOptionName, "Remove only pin objects with the specified statuses (queued,pinning,pinned,failed).").WithDefault([]string{"pinned"}), - cmds.BoolOption(pinForceOptionName, "Remove multiple pins without confirmation.").WithDefault(false), + cmds.StringOption(pinNameOptionName, "Remove pins with names that contain provided value (case-sensitive, exact match)."), + cmds.DelimitedStringsOption(",", pinCIDsOptionName, "Remove pins for the specified CIDs."), + cmds.DelimitedStringsOption(",", pinStatusOptionName, "Remove pins with the specified statuses (queued,pinning,pinned,failed).").WithDefault([]string{"pinned"}), + cmds.BoolOption(pinForceOptionName, "Allow removal of multiple pins matching the query without additional confirmation.").WithDefault(false), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { ctx, cancel := context.WithCancel(req.Context) @@ -359,10 +404,25 @@ var addRemotePinServiceCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Add remote pinning service.", ShortDescription: "Add a credentials for access to a remote pinning service.", + LongDescription: ` +Add a credentials for access to a remote pinning service and store them in the +config under Pinning.RemoteServices map. + +TIP: + + To add services and test them by fetching pin count stats: + + $ ipfs pin remote service add goodsrv https://pin-api.example.com secret-key + $ ipfs pin remote service add badsrv https://bad-api.example.com invalid-key + $ ipfs pin remote service ls --stat + goodsrv https://pin-api.example.com 0/0/0/0 + badsrv https://bad-api.example.com invalid + +`, }, Arguments: []cmds.Argument{ cmds.StringArg(pinServiceNameOptionName, true, false, "Service name."), - cmds.StringArg(pinServiceURLOptionName, true, false, "Service URL."), + cmds.StringArg(pinServiceEndpointOptionName, true, false, "Service endpoint."), cmds.StringArg(pinServiceKeyOptionName, true, false, "Service key."), }, Type: nil, @@ -378,7 +438,7 @@ var addRemotePinServiceCmd = &cmds.Command{ defer repo.Close() if len(req.Arguments) < 3 { - return fmt.Errorf("expecting three arguments: service name, url and key") + return fmt.Errorf("expecting three arguments: service name, endpoint and key") } name := req.Arguments[0] @@ -387,7 +447,7 @@ var addRemotePinServiceCmd = &cmds.Command{ u, err := neturl.ParseRequestURI(url) if err != nil || !strings.HasPrefix(u.Scheme, "http") { - return fmt.Errorf("service url must be a valid HTTP URL") + return fmt.Errorf("service endpoint must be a valid HTTP URL") } cfg, err := repo.Config() @@ -419,7 +479,7 @@ var rmRemotePinServiceCmd = &cmds.Command{ ShortDescription: "Remove credentials for access to a remote pinning service.", }, Arguments: []cmds.Argument{ - cmds.StringArg("remote-pin-service", true, false, "Name of remote pinning service to remove."), + cmds.StringArg(pinServiceNameOptionName, true, false, "Name of remote pinning service to remove."), }, Options: []cmds.Option{}, Type: nil, @@ -454,6 +514,18 @@ var lsRemotePinServiceCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "List remote pinning services.", ShortDescription: "List remote pinning services.", + LongDescription: ` +List remote pinning services. + +By default only a name and an endpoint are listed, however one can pass '--stat' +to test each endpoint by fetching pin counts for each state: + + $ ipfs pin remote service ls --stat + goodsrv https://pin-api.example.com 0/0/0/0 + badsrv https://bad-api.example.com invalid + +TIP: pass '--enc=json' for more useful JSON output. +`, }, Arguments: []cmds.Argument{}, Options: []cmds.Option{ From 1cb90d710976cc7ae31e7e96b1757bd5bd30f3b5 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Mon, 14 Dec 2020 17:52:18 +0100 Subject: [PATCH 092/116] docs: pin remote readability Co-authored-by: Jessica Schilling --- core/commands/pin/remotepin.go | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/core/commands/pin/remotepin.go b/core/commands/pin/remotepin.go index b87a4251f33..c05fe157980 100644 --- a/core/commands/pin/remotepin.go +++ b/core/commands/pin/remotepin.go @@ -106,7 +106,7 @@ The above command will block until remote service returns 'pinned' status, which may take time depending on the size and available providers of the pinned data. -If you prefer to not wait for pinning confirmation and return immediatelly +If you prefer to not wait for pinning confirmation and return immediately after remote service confirms 'queued' status, add the '--background' flag: $ ipfs pin remote add --service=mysrv --name=mypin --background bafkqaaa @@ -240,7 +240,7 @@ Returns a list of objects that are pinned to a remote pinning service. LongDescription: ` Returns a list of objects that are pinned to a remote pinning service. -NOTE: by default it will only show matching objects in 'pinned' state. +NOTE: By default, it will only show matching objects in 'pinned' state. Pass '--status=queued,pinning,pinned,failed' to list pins in all states. `, }, @@ -248,8 +248,8 @@ Pass '--status=queued,pinning,pinned,failed' to list pins in all states. Arguments: []cmds.Argument{}, Options: []cmds.Option{ pinServiceNameOption, - cmds.StringOption(pinNameOptionName, "Return pins with names that contain provided value (case-sensitive, exact match)."), - cmds.DelimitedStringsOption(",", pinCIDsOptionName, "Return pins for the specified CIDs (comma separated)."), + cmds.StringOption(pinNameOptionName, "Return pins with names that contain the value provided (case-sensitive, exact match)."), + cmds.DelimitedStringsOption(",", pinCIDsOptionName, "Return pins for the specified CIDs (comma-separated)."), cmds.DelimitedStringsOption(",", pinStatusOptionName, "Return pins with the specified statuses (queued,pinning,pinned,failed).").WithDefault([]string{"pinned"}), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { @@ -325,11 +325,11 @@ func lsRemote(ctx context.Context, req *cmds.Request, c *pinclient.Client) (chan var rmRemotePinCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Remove pins from remote pinning service.", - ShortDescription: "Removes the remote pin allowing it to be garbage collected if needed.", + ShortDescription: "Removes the remote pin, allowing it to be garbage-collected if needed.", LongDescription: ` -Removes remote pins allowing them to be garbage collected if needed. +Removes remote pins, allowing them to be garbage-collected if needed. -This command accepts the same search query parameters as 'ls' and it is a good +This command accepts the same search query parameters as 'ls', and it is good practice to execute 'ls' before 'rm' to confirm the list of pins to be removed. To remove a single pin for a specific CID: @@ -337,14 +337,14 @@ To remove a single pin for a specific CID: $ ipfs pin remote ls --service=mysrv --cid=bafkqaaa $ ipfs pin remote rm --service=mysrv --cid=bafkqaaa -When more than one pin is matching the query on the remote service an error is -returned. To confirm removal of multiple pins pass '--force': +When more than one pin matches the query on the remote service, an error is +returned. To confirm the removal of multiple pins, pass '--force': $ ipfs pin remote ls --service=mysrv --name=popular-name $ ipfs pin remote rm --service=mysrv --name=popular-name --force NOTE: When no '--status' is passed, implicit '--status=pinned' is used. -To list and then remove all pending pin requests pass an explicit status list: +To list and then remove all pending pin requests, pass an explicit status list: $ ipfs pin remote ls --service=mysrv --status=queued,pinning,failed $ ipfs pin remote rm --service=mysrv --status=queued,pinning,failed --force @@ -403,9 +403,9 @@ To list and then remove all pending pin requests pass an explicit status list: var addRemotePinServiceCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Add remote pinning service.", - ShortDescription: "Add a credentials for access to a remote pinning service.", + ShortDescription: "Add credentials for access to a remote pinning service.", LongDescription: ` -Add a credentials for access to a remote pinning service and store them in the +Add credentials for access to a remote pinning service and store them in the config under Pinning.RemoteServices map. TIP: @@ -517,8 +517,8 @@ var lsRemotePinServiceCmd = &cmds.Command{ LongDescription: ` List remote pinning services. -By default only a name and an endpoint are listed, however one can pass '--stat' -to test each endpoint by fetching pin counts for each state: +By default, only a name and an endpoint are listed; however, one can pass +'--stat' to test each endpoint by fetching pin counts for each state: $ ipfs pin remote service ls --stat goodsrv https://pin-api.example.com 0/0/0/0 From 0b6912e3b3354a095dd9cb70f3d98ef62cb9fc41 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Tue, 15 Dec 2020 19:29:18 +0100 Subject: [PATCH 093/116] refactor: cleanup arg params --- core/commands/pin/remotepin.go | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/core/commands/pin/remotepin.go b/core/commands/pin/remotepin.go index c05fe157980..9d1e3d60bfa 100644 --- a/core/commands/pin/remotepin.go +++ b/core/commands/pin/remotepin.go @@ -56,8 +56,9 @@ const pinNameOptionName = "name" const pinCIDsOptionName = "cid" const pinStatusOptionName = "status" const pinServiceNameOptionName = "service" -const pinServiceEndpointOptionName = "endpoint" -const pinServiceKeyOptionName = "key" +const pinServiceNameArgName = pinServiceNameOptionName +const pinServiceEndpointArgName = "endpoint" +const pinServiceKeyArgName = "key" const pinServiceStatOptionName = "stat" const pinBackgroundOptionName = "background" const pinForceOptionName = "force" @@ -119,7 +120,7 @@ Status of background pin requests can be inspected with the 'ls' command: }, Arguments: []cmds.Argument{ - cmds.StringArg("ipfs-path-or-cid", true, false, "Path to object(s) to be pinned."), + cmds.StringArg("ipfs-path", true, false, "Path to object(s) to be pinned."), }, Options: []cmds.Option{ pinServiceNameOption, @@ -421,9 +422,9 @@ TIP: `, }, Arguments: []cmds.Argument{ - cmds.StringArg(pinServiceNameOptionName, true, false, "Service name."), - cmds.StringArg(pinServiceEndpointOptionName, true, false, "Service endpoint."), - cmds.StringArg(pinServiceKeyOptionName, true, false, "Service key."), + cmds.StringArg(pinServiceNameArgName, true, false, "Service name."), + cmds.StringArg(pinServiceEndpointArgName, true, false, "Service endpoint."), + cmds.StringArg(pinServiceKeyArgName, true, false, "Service key."), }, Type: nil, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { From 5f692a76de01918b202aab1bc5d6657bb177a0ea Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Mon, 14 Dec 2020 19:56:44 +0100 Subject: [PATCH 094/116] fix: normalize remote service endpoint Closes #7826 --- core/commands/pin/remotepin.go | 29 ++++++++++++--- core/commands/pin/remotepin_test.go | 57 +++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 6 deletions(-) create mode 100644 core/commands/pin/remotepin_test.go diff --git a/core/commands/pin/remotepin.go b/core/commands/pin/remotepin.go index 9d1e3d60bfa..7b3de85e24d 100644 --- a/core/commands/pin/remotepin.go +++ b/core/commands/pin/remotepin.go @@ -443,12 +443,12 @@ TIP: } name := req.Arguments[0] - url := strings.TrimSuffix(req.Arguments[1], "/pins") // fix /pins/pins :-) + url := req.Arguments[1] key := req.Arguments[2] - u, err := neturl.ParseRequestURI(url) - if err != nil || !strings.HasPrefix(u.Scheme, "http") { - return fmt.Errorf("service endpoint must be a valid HTTP URL") + endpoint, err := normalizeEndpoint(url) + if err != nil { + return err } cfg, err := repo.Config() @@ -465,7 +465,7 @@ TIP: cfg.Pinning.RemoteServices[name] = config.RemotePinningService{ Api: config.RemotePinningServiceApi{ - Endpoint: url, + Endpoint: endpoint, Key: key, }, } @@ -708,7 +708,11 @@ func getRemotePinService(env cmds.Environment, name string) (*pinclient.Client, if err != nil { return nil, err } - return pinclient.NewClient(url, key), nil + endpoint, err := normalizeEndpoint(url) + if err != nil { + return nil, err + } + return pinclient.NewClient(endpoint, key), nil } func getRemotePinServiceInfo(env cmds.Environment, name string) (url, key string, err error) { @@ -734,3 +738,16 @@ func getRemotePinServiceInfo(env cmds.Environment, name string) (url, key string } return service.Api.Endpoint, service.Api.Key, nil } + +func normalizeEndpoint(endpoint string) (string, error) { + uri, err := neturl.ParseRequestURI(endpoint) + if err != nil || !strings.HasPrefix(uri.Scheme, "http") { + return "", fmt.Errorf("service endpoint must be a valid HTTP URL") + } + // avoid //pins (https://github.com/ipfs/go-ipfs/issues/7826) + uri.Path = strings.TrimSuffix(uri.Path, "/") + // avoid /pins/pins + uri.Path = strings.TrimSuffix(uri.Path, "/pins") + + return uri.String(), nil +} diff --git a/core/commands/pin/remotepin_test.go b/core/commands/pin/remotepin_test.go new file mode 100644 index 00000000000..26265da6fb7 --- /dev/null +++ b/core/commands/pin/remotepin_test.go @@ -0,0 +1,57 @@ +package pin + +import ( + "testing" +) + +func TestNormalizeEndpoint(t *testing.T) { + cases := []struct { + in string + err string + out string + }{ + { + in: "https://1.example.com", + err: "", + out: "https://1.example.com", + }, + { + in: "https://2.example.com/", + err: "", + out: "https://2.example.com", + }, + { + in: "https://3.example.com/pins/", + err: "", + out: "https://3.example.com", + }, + { + in: "https://4.example.com/pins", + err: "", + out: "https://4.example.com", + }, + { + in: "http://192.168.0.5:45000/pins", + err: "", + out: "http://192.168.0.5:45000", + }, + { + in: "foo://4.example.com/pins", + err: "service endpoint must be a valid HTTP URL", + out: "", + }, + } + + for _, tc := range cases { + out, err := normalizeEndpoint(tc.in) + if out != tc.out { + t.Errorf("unexpected endpoint for %q: expected %q; got %q", tc.in, tc.out, out) + continue + } + if err != nil && tc.err != err.Error() { + t.Errorf("unexpected error for %q: expected %q; got %q", tc.in, tc.err, err) + continue + } + } + +} From 6851ede8eb2878a967f8052c4b01b6d1fb946db2 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Tue, 15 Dec 2020 21:58:36 +0100 Subject: [PATCH 095/116] refactor: normalization with path.Clean --- core/commands/pin/remotepin.go | 17 ++++++++++++++--- core/commands/pin/remotepin_test.go | 26 ++++++++++++++++++-------- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/core/commands/pin/remotepin.go b/core/commands/pin/remotepin.go index 7b3de85e24d..b29860a3f4a 100644 --- a/core/commands/pin/remotepin.go +++ b/core/commands/pin/remotepin.go @@ -10,6 +10,7 @@ import ( "time" neturl "net/url" + gopath "path" "golang.org/x/sync/errgroup" @@ -744,10 +745,20 @@ func normalizeEndpoint(endpoint string) (string, error) { if err != nil || !strings.HasPrefix(uri.Scheme, "http") { return "", fmt.Errorf("service endpoint must be a valid HTTP URL") } - // avoid //pins (https://github.com/ipfs/go-ipfs/issues/7826) + + // cleanup trailing and duplicate slashes (https://github.com/ipfs/go-ipfs/issues/7826) + uri.Path = gopath.Clean(uri.Path) + uri.Path = strings.TrimSuffix(uri.Path, ".") uri.Path = strings.TrimSuffix(uri.Path, "/") - // avoid /pins/pins - uri.Path = strings.TrimSuffix(uri.Path, "/pins") + + // remove any query params + if uri.RawQuery != "" || uri.RawFragment != "" { + return "", fmt.Errorf("service endpoint should be provided without any query parameters") + } + + if strings.HasSuffix(uri.Path, "/pins") { + return "", fmt.Errorf("service endpoint should be provided without the /pins suffix") + } return uri.String(), nil } diff --git a/core/commands/pin/remotepin_test.go b/core/commands/pin/remotepin_test.go index 26265da6fb7..d1dfa8fd5e4 100644 --- a/core/commands/pin/remotepin_test.go +++ b/core/commands/pin/remotepin_test.go @@ -22,16 +22,26 @@ func TestNormalizeEndpoint(t *testing.T) { }, { in: "https://3.example.com/pins/", - err: "", - out: "https://3.example.com", + err: "service endpoint should be provided without the /pins suffix", + out: "", }, { in: "https://4.example.com/pins", + err: "service endpoint should be provided without the /pins suffix", + out: "", + }, + { + in: "https://5.example.com/./some//nonsense/../path/../path/", err: "", - out: "https://4.example.com", + out: "https://5.example.com/some/path", + }, + { + in: "https://6.example.com/endpoint/?query=val", + err: "service endpoint should be provided without any query parameters", + out: "", }, { - in: "http://192.168.0.5:45000/pins", + in: "http://192.168.0.5:45000/", err: "", out: "http://192.168.0.5:45000", }, @@ -44,14 +54,14 @@ func TestNormalizeEndpoint(t *testing.T) { for _, tc := range cases { out, err := normalizeEndpoint(tc.in) - if out != tc.out { - t.Errorf("unexpected endpoint for %q: expected %q; got %q", tc.in, tc.out, out) - continue - } if err != nil && tc.err != err.Error() { t.Errorf("unexpected error for %q: expected %q; got %q", tc.in, tc.err, err) continue } + if out != tc.out { + t.Errorf("unexpected endpoint for %q: expected %q; got %q", tc.in, tc.out, out) + continue + } } } From 7313a45bc7e58c8880bc0350acc5a5d909474030 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Tue, 15 Dec 2020 22:22:24 +0100 Subject: [PATCH 096/116] fix: url.RawFragment does not work in go1.14 I don't think we need to worry about #hash, so just removed it --- core/commands/pin/remotepin.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/commands/pin/remotepin.go b/core/commands/pin/remotepin.go index b29860a3f4a..5abbc7fb6ea 100644 --- a/core/commands/pin/remotepin.go +++ b/core/commands/pin/remotepin.go @@ -752,7 +752,7 @@ func normalizeEndpoint(endpoint string) (string, error) { uri.Path = strings.TrimSuffix(uri.Path, "/") // remove any query params - if uri.RawQuery != "" || uri.RawFragment != "" { + if uri.RawQuery != "" { return "", fmt.Errorf("service endpoint should be provided without any query parameters") } From fc4095cfb3f8c2c958a9bcd583698070ed1f38d5 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Tue, 15 Dec 2020 23:24:48 +0100 Subject: [PATCH 097/116] =?UTF-8?q?refactor:=20url=20=E2=86=92=20endpoint?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://github.com/ipfs/go-ipfs/pull/7828#discussion_r543520089 --- core/commands/pin/remotepin.go | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/core/commands/pin/remotepin.go b/core/commands/pin/remotepin.go index 5abbc7fb6ea..80572bfb80a 100644 --- a/core/commands/pin/remotepin.go +++ b/core/commands/pin/remotepin.go @@ -444,13 +444,11 @@ TIP: } name := req.Arguments[0] - url := req.Arguments[1] - key := req.Arguments[2] - - endpoint, err := normalizeEndpoint(url) + endpoint, err := normalizeEndpoint(req.Arguments[1]) if err != nil { return err } + key := req.Arguments[2] cfg, err := repo.Config() if err != nil { @@ -705,18 +703,14 @@ func getRemotePinService(env cmds.Environment, name string) (*pinclient.Client, if name == "" { return nil, fmt.Errorf("remote pinning service name not specified") } - url, key, err := getRemotePinServiceInfo(env, name) - if err != nil { - return nil, err - } - endpoint, err := normalizeEndpoint(url) + endpoint, key, err := getRemotePinServiceInfo(env, name) if err != nil { return nil, err } return pinclient.NewClient(endpoint, key), nil } -func getRemotePinServiceInfo(env cmds.Environment, name string) (url, key string, err error) { +func getRemotePinServiceInfo(env cmds.Environment, name string) (endpoint, key string, err error) { cfgRoot, err := cmdenv.GetConfigRoot(env) if err != nil { return "", "", err @@ -737,7 +731,11 @@ func getRemotePinServiceInfo(env cmds.Environment, name string) (url, key string if !present { return "", "", fmt.Errorf("service not known") } - return service.Api.Endpoint, service.Api.Key, nil + endpoint, err = normalizeEndpoint(service.Api.Endpoint) + if err != nil { + return "", "", err + } + return endpoint, service.Api.Key, nil } func normalizeEndpoint(endpoint string) (string, error) { From e0d484431adc292e1aa63aeb36cd2298486c743f Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Wed, 27 Jan 2021 14:07:04 -0500 Subject: [PATCH 098/116] test: add sharness tests for remote pinning service endpoints that are not http(s) URIs --- test/sharness/t0700-remotepin.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/sharness/t0700-remotepin.sh b/test/sharness/t0700-remotepin.sh index b03d4177d5b..cac374193ad 100755 --- a/test/sharness/t0700-remotepin.sh +++ b/test/sharness/t0700-remotepin.sh @@ -37,6 +37,12 @@ test_expect_success "creating test user on remote pinning service" ' ipfs pin remote service add test_invalid_url_dns_svc https://invalid-service.example.com fake_api_key ' +# add a service with a invalid endpoint +test_expect_success "adding remote service with invalid endpoint" ' + test_expect_code 1 ipfs pin remote service add test_endpoint_no_protocol invalid-service.example.com fake_api_key && + test_expect_code 1 ipfs pin remote service add test_endpoint_bad_protocol xyz://invalid-service.example.com fake_api_key +' + test_expect_success "test 'ipfs pin remote service ls'" ' ipfs pin remote service ls | tee ls_out && grep -q test_pin_svc ls_out && From 61f3a2f3a2e62b47f058029f77e95f9a11b38b4c Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Wed, 27 Jan 2021 14:09:29 -0500 Subject: [PATCH 099/116] fix: restrict remote pinning service endpoint URIs to HTTP/HTTPS --- core/commands/pin/remotepin.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/commands/pin/remotepin.go b/core/commands/pin/remotepin.go index 80572bfb80a..606b23f6d55 100644 --- a/core/commands/pin/remotepin.go +++ b/core/commands/pin/remotepin.go @@ -740,7 +740,7 @@ func getRemotePinServiceInfo(env cmds.Environment, name string) (endpoint, key s func normalizeEndpoint(endpoint string) (string, error) { uri, err := neturl.ParseRequestURI(endpoint) - if err != nil || !strings.HasPrefix(uri.Scheme, "http") { + if err != nil || !(uri.Scheme == "http" || uri.Scheme == "https") { return "", fmt.Errorf("service endpoint must be a valid HTTP URL") } From 3bca93787a7af6e0ad0f4b6866d698f1c614cf79 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Thu, 28 Jan 2021 17:23:46 +0100 Subject: [PATCH 100/116] docs: comma delimited options in pin remote --help This adds clarification suggested in https://github.com/ipfs/go-ipfs/pull/7823#pullrequestreview-577889138 --- core/commands/pin/remotepin.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/core/commands/pin/remotepin.go b/core/commands/pin/remotepin.go index 9d1e3d60bfa..c7b365f8ec7 100644 --- a/core/commands/pin/remotepin.go +++ b/core/commands/pin/remotepin.go @@ -112,7 +112,14 @@ after remote service confirms 'queued' status, add the '--background' flag: $ ipfs pin remote add --service=mysrv --name=mypin --background bafkqaaa -Status of background pin requests can be inspected with the 'ls' command: +Status of background pin requests can be inspected with the 'ls' command. + +To list all pins for the CID across all statuses: + + $ ipfs pin remote ls --service=mysrv --cid=bafkqaaa --status=queued \ + --status=pinning --status=pinned --status=failed + +NOTE: a comma-separated notation is supported in CLI for convenience: $ ipfs pin remote ls --service=mysrv --cid=bafkqaaa --status=queued,pinning,pinned,failed From 6f6f04543b07fcae08fd8b516082672d730ba8cd Mon Sep 17 00:00:00 2001 From: Andrew Gillis Date: Thu, 28 Jan 2021 12:15:49 -0800 Subject: [PATCH 101/116] Improve error message when running key command that locks repo (#7821) * Improve error message when running key commands that must be run when the daemon is not already running Fixes Issue #7814 `ipfs key export` now does a PreRun check like `ipfs key rotate` was to give a better error to the user then "someone else has the lock" in the event that the daemon is running while trying to execute these offline-only commands. While unlikely the "someone else has the lock" error can still be shown if two processes try and grab the repo lock at the same time. This PreRun function is also exported so it can be used by `ipfs init` where it was originally copied from. * Added more `ipfs key` command tests When daemon is running: - Test that import works - Test that export fails - Test that rotate fails --- cmd/ipfs/init.go | 17 +-------------- core/commands/keystore.go | 37 +++++++++++++++++++-------------- test/sharness/t0165-keystore.sh | 18 ++++++++++++++++ 3 files changed, 40 insertions(+), 32 deletions(-) diff --git a/cmd/ipfs/init.go b/cmd/ipfs/init.go index 0842b71976d..f419604f2e3 100644 --- a/cmd/ipfs/init.go +++ b/cmd/ipfs/init.go @@ -69,22 +69,7 @@ environment variable: }, NoRemote: true, Extra: commands.CreateCmdExtras(commands.SetDoesNotUseRepo(true), commands.SetDoesNotUseConfigAsInput(true)), - PreRun: func(req *cmds.Request, env cmds.Environment) error { - cctx := env.(*oldcmds.Context) - daemonLocked, err := fsrepo.LockedByOtherProcess(cctx.ConfigRoot) - if err != nil { - return err - } - - log.Info("checking if daemon is running...") - if daemonLocked { - log.Debug("ipfs daemon is running") - e := "ipfs daemon is running. please stop it to run this command" - return cmds.ClientError(e) - } - - return nil - }, + PreRun: commands.DaemonNotRunning, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { cctx := env.(*oldcmds.Context) empty, _ := req.Options[emptyRepoOptionName].(bool) diff --git a/core/commands/keystore.go b/core/commands/keystore.go index 5f2388ddeae..9b86ba36b56 100644 --- a/core/commands/keystore.go +++ b/core/commands/keystore.go @@ -150,6 +150,7 @@ path can be specified with '--output=' or '-o='. cmds.StringOption(outputOptionName, "o", "The path where the output should be stored."), }, NoRemote: true, + PreRun: DaemonNotRunning, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { name := req.Arguments[0] @@ -459,22 +460,7 @@ environment variable: cmds.IntOption(keyStoreSizeOptionName, "s", "size of the key to generate"), }, NoRemote: true, - PreRun: func(req *cmds.Request, env cmds.Environment) error { - cctx := env.(*oldcmds.Context) - daemonLocked, err := fsrepo.LockedByOtherProcess(cctx.ConfigRoot) - if err != nil { - return err - } - - log.Info("checking if daemon is running...") - if daemonLocked { - log.Debug("ipfs daemon is running") - e := "ipfs daemon is running. please stop it to run this command" - return cmds.ClientError(e) - } - - return nil - }, + PreRun: DaemonNotRunning, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { cctx := env.(*oldcmds.Context) nBitsForKeypair, nBitsGiven := req.Options[keyStoreSizeOptionName].(int) @@ -556,3 +542,22 @@ func keyOutputListEncoders() cmds.EncoderFunc { return nil }) } + +// DaemonNotRunning checks to see if the ipfs repo is locked, indicating that +// the daemon is running, and returns and error if the daemon is running. +func DaemonNotRunning(req *cmds.Request, env cmds.Environment) error { + cctx := env.(*oldcmds.Context) + daemonLocked, err := fsrepo.LockedByOtherProcess(cctx.ConfigRoot) + if err != nil { + return err + } + + log.Info("checking if daemon is running...") + if daemonLocked { + log.Debug("ipfs daemon is running") + e := "ipfs daemon is running. please stop it to run this command" + return cmds.ClientError(e) + } + + return nil +} diff --git a/test/sharness/t0165-keystore.sh b/test/sharness/t0165-keystore.sh index 07a9ad9fe8e..0bbbe91aca5 100755 --- a/test/sharness/t0165-keystore.sh +++ b/test/sharness/t0165-keystore.sh @@ -167,6 +167,24 @@ ipfs key rm key_ed25519 test_must_fail ipfs key rename -f fooed self 2>&1 | tee key_rename_out && grep -q "Error: cannot overwrite key with name" key_rename_out ' + + test_launch_ipfs_daemon + + test_expect_success "online import 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_must_fail "online export rsa key" ' + ipfs key export generated_rsa_key + ' + + test_must_fail "online rotate rsa key" ' + ipfs key rotate + ' + + test_kill_ipfs_daemon + } test_check_rsa2048_sk() { From dd295e45608560d2ada7d7c8a30f1eef3f4019bb Mon Sep 17 00:00:00 2001 From: "@RubenKelevra" Date: Thu, 28 Jan 2021 21:22:36 +0100 Subject: [PATCH 102/116] show the domain name with the error (#7886) * show the domain name if DNSLink failed to resolve a domain because it wasn't a valid domain name Original author: @AluisioASG --- namesys/dns.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/namesys/dns.go b/namesys/dns.go index 984a27aa80c..0b48ad34bdb 100644 --- a/namesys/dns.go +++ b/namesys/dns.go @@ -5,6 +5,7 @@ import ( "errors" "net" "strings" + "fmt" path "github.com/ipfs/go-path" opts "github.com/ipfs/interface-go-ipfs-core/options/namesys" @@ -53,7 +54,7 @@ func (r *DNSResolver) resolveOnceAsync(ctx context.Context, name string, options domain := segments[0] if !isd.IsDomain(domain) { - out <- onceResult{err: errors.New("not a valid domain name")} + out <- onceResult{err: fmt.Errorf("not a valid domain name: %s", domain)} close(out) return out } From 50f066f05ed6bd5fd8c52ae49c473fc5bd7acc72 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 28 Jan 2021 11:25:06 +0000 Subject: [PATCH 103/116] chore(deps): bump github.com/ipfs/go-graphsync from 0.5.2 to 0.6.0 Bumps [github.com/ipfs/go-graphsync](https://github.com/ipfs/go-graphsync) from 0.5.2 to 0.6.0. - [Release notes](https://github.com/ipfs/go-graphsync/releases) - [Changelog](https://github.com/ipfs/go-graphsync/blob/master/CHANGELOG.md) - [Commits](https://github.com/ipfs/go-graphsync/compare/v0.5.2...v0.6.0) Signed-off-by: dependabot-preview[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 2a3df9d3dfe..ff350c01840 100644 --- a/go.mod +++ b/go.mod @@ -28,7 +28,7 @@ require ( github.com/ipfs/go-ds-measure v0.1.0 github.com/ipfs/go-filestore v0.0.3 github.com/ipfs/go-fs-lock v0.0.6 - github.com/ipfs/go-graphsync v0.5.2 + github.com/ipfs/go-graphsync v0.6.0 github.com/ipfs/go-ipfs-blockstore v0.1.4 github.com/ipfs/go-ipfs-chunker v0.0.5 github.com/ipfs/go-ipfs-cmds v0.6.0 diff --git a/go.sum b/go.sum index 9d54212d701..50ca112faed 100644 --- a/go.sum +++ b/go.sum @@ -316,8 +316,8 @@ github.com/ipfs/go-filestore v0.0.3 h1:MhZ1jT5K3NewZwim6rS/akcJLm1xM+r6nz6foeB9E github.com/ipfs/go-filestore v0.0.3/go.mod h1:dvXRykFzyyXN2CdNlRGzDAkXMDPyI+D7JE066SiKLSE= github.com/ipfs/go-fs-lock v0.0.6 h1:sn3TWwNVQqSeNjlWy6zQ1uUGAZrV3hPOyEA6y1/N2a0= github.com/ipfs/go-fs-lock v0.0.6/go.mod h1:OTR+Rj9sHiRubJh3dRhD15Juhd/+w6VPOY28L7zESmM= -github.com/ipfs/go-graphsync v0.5.2 h1:USD+daaSC+7pLHCxROThSaF6SF7WYXF03sjrta0rCfA= -github.com/ipfs/go-graphsync v0.5.2/go.mod h1:e2ZxnClqBBYAtd901g9vXMJzS47labjAtOzsWtOzKNk= +github.com/ipfs/go-graphsync v0.6.0 h1:x6UvDUGA7wjaKNqx5Vbo7FGT8aJ5ryYA0dMQ5jN3dF0= +github.com/ipfs/go-graphsync v0.6.0/go.mod h1:e2ZxnClqBBYAtd901g9vXMJzS47labjAtOzsWtOzKNk= 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 h1:2SGI6U1B44aODevza8Rde3+dY30Pb+lbcObe1LETxOQ= From eb894dca7b78446c13ffc995631cd25e569657bc Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 28 Jan 2021 20:45:10 +0000 Subject: [PATCH 104/116] chore(deps): bump github.com/gogo/protobuf from 1.3.1 to 1.3.2 Bumps [github.com/gogo/protobuf](https://github.com/gogo/protobuf) from 1.3.1 to 1.3.2. - [Release notes](https://github.com/gogo/protobuf/releases) - [Commits](https://github.com/gogo/protobuf/compare/v1.3.1...v1.3.2) Signed-off-by: dependabot-preview[bot] --- go.mod | 6 +++--- go.sum | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 2a3df9d3dfe..76635571ff8 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/fsnotify/fsnotify v1.4.9 github.com/gabriel-vasile/mimetype v1.1.2 github.com/go-bindata/go-bindata/v3 v3.1.3 - github.com/gogo/protobuf v1.3.1 + github.com/gogo/protobuf v1.3.2 github.com/hashicorp/go-multierror v1.1.0 github.com/hashicorp/golang-lru v0.5.4 github.com/ipfs/go-bitswap v0.3.3 @@ -107,8 +107,8 @@ require ( go.uber.org/zap v1.16.0 golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect - golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 - golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 + golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 + golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f ) go 1.14 diff --git a/go.sum b/go.sum index 9d54212d701..f6bcdc8ba86 100644 --- a/go.sum +++ b/go.sum @@ -169,6 +169,8 @@ github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zV 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-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -457,6 +459,8 @@ github.com/kami-zh/go-capturer v0.0.0-20171211120116-e492ea43421d/go.mod h1:P2vi github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0 h1:reN85Pxc5larApoH1keMBiu2GWtPqXQ1nc9gx+jOU+E= 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/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= @@ -1029,7 +1033,9 @@ github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee h1:lYbXeSv 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/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= @@ -1145,10 +1151,13 @@ golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/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-20200520004742-59133d7f0dd7/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 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= 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= @@ -1167,6 +1176,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 h1:qwRHBd0NqMbJxfbotnDhm2ByMI1Shq4Y6oRJo21SGJA= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 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= @@ -1212,6 +1223,8 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 h1:ogLJMz+qpzav7lGMh10LMvAkM/fAoGlaiiHYiFYdm80= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 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= @@ -1257,12 +1270,17 @@ golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/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-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200827010519-17fd2f27a9e3 h1:r3P/5xOq/dK1991B65Oy6E1fRF/2d/fSYZJ/fXGVfJc= golang.org/x/tools v0.0.0-20200827010519-17fd2f27a9e3/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a h1:CB3a9Nez8M13wwlr/E2YtwoU+qYHKfC+JrDa45RXXoQ= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 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 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/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= From a2f960c12e0054716f237f4fa8ea70d0ee33a5f5 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 28 Jan 2021 20:41:42 +0000 Subject: [PATCH 105/116] chore(deps): bump github.com/stretchr/testify from 1.6.1 to 1.7.0 Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.6.1 to 1.7.0. - [Release notes](https://github.com/stretchr/testify/releases) - [Commits](https://github.com/stretchr/testify/compare/v1.6.1...v1.7.0) Signed-off-by: dependabot-preview[bot] --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 2a3df9d3dfe..6868980a04a 100644 --- a/go.mod +++ b/go.mod @@ -96,7 +96,7 @@ require ( github.com/opentracing/opentracing-go v1.2.0 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.7.1 - github.com/stretchr/testify v1.6.1 + github.com/stretchr/testify v1.7.0 github.com/syndtr/goleveldb v1.0.0 github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc github.com/whyrusleeping/go-sysinfo v0.0.0-20190219211824-4a357d4b90b1 diff --git a/go.sum b/go.sum index 9d54212d701..9d8df1acc00 100644 --- a/go.sum +++ b/go.sum @@ -988,6 +988,8 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P 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 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/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= From 8794928c31437f0bcf877326674b268f9528ae42 Mon Sep 17 00:00:00 2001 From: Petar Maymounkov Date: Thu, 28 Jan 2021 15:58:44 -0800 Subject: [PATCH 106/116] add remote pinning policy for mfs (#7798) * remote pinning service MFS policy * update go-ipfs-config * hardening secret sanitization in `ipfs config` commands Co-authored-by: Adin Schmahmann Co-authored-by: Marcin Rataj --- cmd/ipfs/daemon.go | 3 + cmd/ipfs/pinmfs.go | 266 +++++++++++++++++++++++++++++++ cmd/ipfs/pinmfs_test.go | 179 +++++++++++++++++++++ commands/context.go | 6 +- core/commands/config.go | 180 ++++++++++++--------- core/commands/config_test.go | 17 ++ core/commands/pin/remotepin.go | 9 +- go.mod | 2 +- go.sum | 4 +- test/sharness/t0700-remotepin.sh | 81 +++++++--- 10 files changed, 641 insertions(+), 106 deletions(-) create mode 100644 cmd/ipfs/pinmfs.go create mode 100644 cmd/ipfs/pinmfs_test.go create mode 100644 core/commands/config_test.go diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/daemon.go index b3cb9f7b523..329a29c4cf4 100644 --- a/cmd/ipfs/daemon.go +++ b/cmd/ipfs/daemon.go @@ -439,6 +439,9 @@ func daemonFunc(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment // initialize metrics collector prometheus.MustRegister(&corehttp.IpfsNodeCollector{Node: node}) + // start MFS pinning thread + startPinMFS(daemonConfigPollInterval, cctx, &ipfsPinMFSNode{node}) + // The daemon is *finally* ready. fmt.Printf("Daemon is ready\n") notifyReady() diff --git a/cmd/ipfs/pinmfs.go b/cmd/ipfs/pinmfs.go new file mode 100644 index 00000000000..5d17f3013f3 --- /dev/null +++ b/cmd/ipfs/pinmfs.go @@ -0,0 +1,266 @@ +package main + +import ( + "context" + "fmt" + "time" + + "github.com/libp2p/go-libp2p-core/host" + peer "github.com/libp2p/go-libp2p-core/peer" + + cid "github.com/ipfs/go-cid" + ipld "github.com/ipfs/go-ipld-format" + logging "github.com/ipfs/go-log" + pinclient "github.com/ipfs/go-pinning-service-http-client" + + config "github.com/ipfs/go-ipfs-config" + "github.com/ipfs/go-ipfs/core" +) + +// mfslog is the logger for remote mfs pinning +var mfslog = logging.Logger("remotepinning/mfs") + +type lastPin struct { + Time time.Time + ServiceName string + ServiceConfig config.RemotePinningService + CID cid.Cid +} + +func (x lastPin) IsValid() bool { + return x != lastPin{} +} + +const daemonConfigPollInterval = time.Minute / 2 +const defaultRepinInterval = 5 * time.Minute + +type pinMFSContext interface { + Context() context.Context + GetConfigNoCache() (*config.Config, error) +} + +type pinMFSNode interface { + RootNode() (ipld.Node, error) + Identity() peer.ID + PeerHost() host.Host +} + +type ipfsPinMFSNode struct { + node *core.IpfsNode +} + +func (x *ipfsPinMFSNode) RootNode() (ipld.Node, error) { + return x.node.FilesRoot.GetDirectory().GetNode() +} + +func (x *ipfsPinMFSNode) Identity() peer.ID { + return x.node.Identity +} + +func (x *ipfsPinMFSNode) PeerHost() host.Host { + return x.node.PeerHost +} + +func startPinMFS(configPollInterval time.Duration, cctx pinMFSContext, node pinMFSNode) { + errCh := make(chan error) + go pinMFSOnChange(configPollInterval, cctx, node, errCh) + go func() { + for { + select { + case err, isOpen := <-errCh: + if !isOpen { + return + } + mfslog.Errorf("%v", err) + case <-cctx.Context().Done(): + return + } + } + }() +} + +func pinMFSOnChange(configPollInterval time.Duration, cctx pinMFSContext, node pinMFSNode, errCh chan<- error) { + defer close(errCh) + + var tmo *time.Timer + defer func() { + if tmo != nil { + tmo.Stop() + } + }() + + lastPins := map[string]lastPin{} + for { + // polling sleep + if tmo == nil { + tmo = time.NewTimer(configPollInterval) + } else { + tmo.Reset(configPollInterval) + } + select { + case <-cctx.Context().Done(): + return + case <-tmo.C: + } + + // reread the config, which may have changed in the meantime + cfg, err := cctx.GetConfigNoCache() + if err != nil { + select { + case errCh <- fmt.Errorf("pinning reading config (%v)", err): + case <-cctx.Context().Done(): + return + } + continue + } + mfslog.Debugf("pinning loop is awake, %d remote services", len(cfg.Pinning.RemoteServices)) + + // get the most recent MFS root cid + rootNode, err := node.RootNode() + if err != nil { + select { + case errCh <- fmt.Errorf("pinning reading MFS root (%v)", err): + case <-cctx.Context().Done(): + return + } + continue + } + rootCid := rootNode.Cid() + + // pin to all remote services in parallel + pinAllMFS(cctx.Context(), node, cfg, rootCid, lastPins, errCh) + } +} + +// pinAllMFS pins on all remote services in parallel to overcome DoS attacks. +func pinAllMFS(ctx context.Context, node pinMFSNode, cfg *config.Config, rootCid cid.Cid, lastPins map[string]lastPin, errCh chan<- error) { + ch := make(chan lastPin, len(cfg.Pinning.RemoteServices)) + for svcName_, svcConfig_ := range cfg.Pinning.RemoteServices { + // skip services where MFS is not enabled + svcName, svcConfig := svcName_, svcConfig_ + mfslog.Debugf("pinning considering service %s for mfs pinning", svcName) + if !svcConfig.Policies.MFS.Enable { + mfslog.Debugf("pinning service %s is not enabled", svcName) + ch <- lastPin{} + continue + } + // read mfs pin interval for this service + var repinInterval time.Duration + if svcConfig.Policies.MFS.RepinInterval == "" { + repinInterval = defaultRepinInterval + } else { + var err error + repinInterval, err = time.ParseDuration(svcConfig.Policies.MFS.RepinInterval) + if err != nil { + select { + case errCh <- fmt.Errorf("remote pinning service %s has invalid MFS.RepinInterval (%v)", svcName, err): + case <-ctx.Done(): + } + ch <- lastPin{} + continue + } + } + + // do nothing, if MFS has not changed since last pin on the exact same service or waiting for MFS.RepinInterval + if last, ok := lastPins[svcName]; ok { + if last.ServiceConfig == svcConfig && (last.CID == rootCid || time.Since(last.Time) < repinInterval) { + if last.CID == rootCid { + mfslog.Debugf("pinning MFS root to %s: pin for %s exists since %s, skipping", svcName, rootCid, last.Time.String()) + } else { + mfslog.Debugf("pinning MFS root to %s: skipped due to MFS.RepinInterval=%s (remaining: %s)", svcName, repinInterval.String(), (repinInterval - time.Since(last.Time)).String()) + } + ch <- lastPin{} + continue + } + } + + mfslog.Debugf("pinning MFS root %s to %s", rootCid, svcName) + go func() { + if r, err := pinMFS(ctx, node, rootCid, svcName, svcConfig); err != nil { + select { + case errCh <- fmt.Errorf("pinning MFS root %s to %s (%v)", rootCid, svcName, err): + case <-ctx.Done(): + } + ch <- lastPin{} + } else { + ch <- r + } + }() + } + for i := 0; i < len(cfg.Pinning.RemoteServices); i++ { + if x := <-ch; x.IsValid() { + lastPins[x.ServiceName] = x + } + } +} + +func pinMFS( + ctx context.Context, + node pinMFSNode, + cid cid.Cid, + svcName string, + svcConfig config.RemotePinningService, +) (lastPin, error) { + c := pinclient.NewClient(svcConfig.API.Endpoint, svcConfig.API.Key) + + pinName := svcConfig.Policies.MFS.PinName + if pinName == "" { + pinName = fmt.Sprintf("policy/%s/mfs", node.Identity().String()) + } + + // check if MFS pin exists (across all possible states) and inspect its CID + pinStatuses := []pinclient.Status{pinclient.StatusQueued, pinclient.StatusPinning, pinclient.StatusPinned, pinclient.StatusFailed} + lsPinCh, lsErrCh := c.Ls(ctx, pinclient.PinOpts.FilterName(pinName), pinclient.PinOpts.FilterStatus(pinStatuses...)) + existingRequestID := "" // is there any pre-existing MFS pin with pinName (for any CID)? + alreadyPinned := false // is CID for current MFS already pinned? + pinTime := time.Now().UTC() + for ps := range lsPinCh { + existingRequestID = ps.GetRequestId() + if ps.GetPin().GetCid() == cid && ps.GetStatus() != pinclient.StatusFailed { + alreadyPinned = true + pinTime = ps.GetCreated().UTC() + break + } + } + for range lsPinCh { // in case the prior loop exits early + } + if err := <-lsErrCh; err != nil { + return lastPin{}, fmt.Errorf("error while listing remote pins: %v", err) + } + + // CID of the current MFS root is already pinned, nothing to do + if alreadyPinned { + mfslog.Debugf("pinning MFS to %s: pin for %s exists since %s, skipping", svcName, cid, pinTime.String()) + return lastPin{Time: pinTime, ServiceName: svcName, ServiceConfig: svcConfig, CID: cid}, nil + } + + // Prepare Pin.name + addOpts := []pinclient.AddOption{pinclient.PinOpts.WithName(pinName)} + + // Prepare Pin.origins + // Add own multiaddrs to the 'origins' array, so Pinning Service can + // use that as a hint and connect back to us (if possible) + if node.PeerHost() != nil { + addrs, err := peer.AddrInfoToP2pAddrs(host.InfoFromHost(node.PeerHost())) + if err != nil { + return lastPin{}, err + } + addOpts = append(addOpts, pinclient.PinOpts.WithOrigins(addrs...)) + } + + // Create or replace pin for MFS root + if existingRequestID != "" { + mfslog.Debugf("pinning to %s: replacing existing MFS root pin with %s", svcName, cid) + _, err := c.Replace(ctx, existingRequestID, cid, addOpts...) + if err != nil { + return lastPin{}, err + } + } else { + mfslog.Debugf("pinning to %s: creating a new MFS root pin for %s", svcName, cid) + _, err := c.Add(ctx, cid, addOpts...) + if err != nil { + return lastPin{}, err + } + } + return lastPin{Time: pinTime, ServiceName: svcName, ServiceConfig: svcConfig, CID: cid}, nil +} diff --git a/cmd/ipfs/pinmfs_test.go b/cmd/ipfs/pinmfs_test.go new file mode 100644 index 00000000000..42ffe9d408e --- /dev/null +++ b/cmd/ipfs/pinmfs_test.go @@ -0,0 +1,179 @@ +package main + +import ( + "context" + "fmt" + "strings" + "testing" + "time" + + config "github.com/ipfs/go-ipfs-config" + ipld "github.com/ipfs/go-ipld-format" + "github.com/ipfs/go-merkledag" + "github.com/libp2p/go-libp2p-core/host" + peer "github.com/libp2p/go-libp2p-core/peer" +) + +type testPinMFSContext struct { + ctx context.Context + cfg *config.Config + err error +} + +func (x *testPinMFSContext) Context() context.Context { + return x.ctx +} + +func (x *testPinMFSContext) GetConfigNoCache() (*config.Config, error) { + return x.cfg, x.err +} + +type testPinMFSNode struct { + err error +} + +func (x *testPinMFSNode) RootNode() (ipld.Node, error) { + return merkledag.NewRawNode([]byte{0x01}), x.err +} + +func (x *testPinMFSNode) Identity() peer.ID { + return peer.ID("test_id") +} + +func (x *testPinMFSNode) PeerHost() host.Host { + return nil +} + +var testConfigPollInterval = time.Second + +func isErrorSimilar(e1, e2 error) bool { + switch { + case e1 == nil && e2 == nil: + return true + case e1 != nil && e2 == nil: + return false + case e1 == nil && e2 != nil: + return false + default: + return strings.Contains(e1.Error(), e2.Error()) || strings.Contains(e2.Error(), e1.Error()) + } +} + +func TestPinMFSConfigError(t *testing.T) { + ctx := &testPinMFSContext{ + ctx: context.Background(), + cfg: nil, + err: fmt.Errorf("couldn't read config"), + } + node := &testPinMFSNode{} + errCh := make(chan error) + go pinMFSOnChange(testConfigPollInterval, ctx, node, errCh) + if !isErrorSimilar(<-errCh, ctx.err) { + t.Errorf("error did not propagate") + } + if !isErrorSimilar(<-errCh, ctx.err) { + t.Errorf("error did not propagate") + } +} + +func TestPinMFSRootNodeError(t *testing.T) { + ctx := &testPinMFSContext{ + ctx: context.Background(), + cfg: &config.Config{ + Pinning: config.Pinning{}, + }, + err: nil, + } + node := &testPinMFSNode{ + err: fmt.Errorf("cannot create root node"), + } + errCh := make(chan error) + go pinMFSOnChange(testConfigPollInterval, ctx, node, errCh) + if !isErrorSimilar(<-errCh, node.err) { + t.Errorf("error did not propagate") + } + if !isErrorSimilar(<-errCh, node.err) { + t.Errorf("error did not propagate") + } +} + +func TestPinMFSService(t *testing.T) { + cfg_invalid_interval := &config.Config{ + Pinning: config.Pinning{ + RemoteServices: map[string]config.RemotePinningService{ + "disabled": { + Policies: config.RemotePinningServicePolicies{ + MFS: config.RemotePinningServiceMFSPolicy{ + Enable: false, + }, + }, + }, + "invalid_interval": { + Policies: config.RemotePinningServicePolicies{ + MFS: config.RemotePinningServiceMFSPolicy{ + Enable: true, + RepinInterval: "INVALID_INTERVAL", + }, + }, + }, + }, + }, + } + cfg_valid_unnamed := &config.Config{ + Pinning: config.Pinning{ + RemoteServices: map[string]config.RemotePinningService{ + "valid_unnamed": { + Policies: config.RemotePinningServicePolicies{ + MFS: config.RemotePinningServiceMFSPolicy{ + Enable: true, + PinName: "", + RepinInterval: "2s", + }, + }, + }, + }, + }, + } + cfg_valid_named := &config.Config{ + Pinning: config.Pinning{ + RemoteServices: map[string]config.RemotePinningService{ + "valid_named": { + Policies: config.RemotePinningServicePolicies{ + MFS: config.RemotePinningServiceMFSPolicy{ + Enable: true, + PinName: "pin_name", + RepinInterval: "2s", + }, + }, + }, + }, + }, + } + testPinMFSServiceWithError(t, cfg_invalid_interval, "remote pinning service invalid_interval has invalid MFS.RepinInterval") + testPinMFSServiceWithError(t, cfg_valid_unnamed, "error while listing remote pins: empty response from remote pinning service") + testPinMFSServiceWithError(t, cfg_valid_named, "error while listing remote pins: empty response from remote pinning service") +} + +func testPinMFSServiceWithError(t *testing.T, cfg *config.Config, expectedErrorPrefix string) { + goctx, cancel := context.WithCancel(context.Background()) + ctx := &testPinMFSContext{ + ctx: goctx, + cfg: cfg, + err: nil, + } + node := &testPinMFSNode{ + err: nil, + } + errCh := make(chan error) + go pinMFSOnChange(testConfigPollInterval, ctx, node, errCh) + defer cancel() + // first pass through the pinning loop + err := <-errCh + if !strings.Contains((err).Error(), expectedErrorPrefix) { + t.Errorf("expecting error containing %q", expectedErrorPrefix) + } + // second pass through the pinning loop + if !strings.Contains((err).Error(), expectedErrorPrefix) { + t.Errorf("expecting error containing %q", expectedErrorPrefix) + } +} diff --git a/commands/context.go b/commands/context.go index 99bec345466..e306821e83c 100644 --- a/commands/context.go +++ b/commands/context.go @@ -10,7 +10,7 @@ import ( coreapi "github.com/ipfs/go-ipfs/core/coreapi" loader "github.com/ipfs/go-ipfs/plugin/loader" - "github.com/ipfs/go-ipfs-cmds" + 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" @@ -48,6 +48,10 @@ func (c *Context) GetConfig() (*config.Config, error) { return c.config, err } +func (c *Context) GetConfigNoCache() (*config.Config, error) { + return c.LoadConfig(c.ConfigRoot) +} + // GetNode returns the node of the current Command execution // context. It may construct it with the provided function. func (c *Context) GetNode() (*core.IpfsNode, error) { diff --git a/core/commands/config.go b/core/commands/config.go index 3931bfc25dc..cc6374c24ca 100644 --- a/core/commands/config.go +++ b/core/commands/config.go @@ -36,8 +36,6 @@ const ( configDryRunOptionName = "dry-run" ) -var tryRemoteServiceApiErr = errors.New("cannot show or change pinning services through this API (try: ipfs pin remote service --help)") - var ConfigCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Get and set ipfs config values.", @@ -90,8 +88,8 @@ Set the value of the 'Datastore.Path' key: // Temporary fix until we move ApiKey secrets out of the config file // (remote services are a map, so more advanced blocking is required) - if blocked := inBlockedScope(key, config.RemoteServicesSelector); blocked { - return tryRemoteServiceApiErr + if blocked := matchesGlobPrefix(key, config.PinningConcealSelector); blocked { + return errors.New("cannot show or change pinning services credentials") } cfgRoot, err := cmdenv.GetConfigRoot(env) @@ -148,22 +146,31 @@ Set the value of the 'Datastore.Path' key: Type: ConfigField{}, } -// Returns bool to indicate if tested key is in the blocked scope. -// (scope includes parent, direct, and child match) -func inBlockedScope(testKey string, blockedScope string) bool { - blockedScope = strings.ToLower(blockedScope) - roots := strings.Split(strings.ToLower(testKey), ".") - var scope []string - for _, name := range roots { - scope := append(scope, name) - impactedKey := strings.Join(scope, ".") - // blockedScope=foo.bar.BLOCKED should return true - // for parent and child impactedKeys: foo.bar and foo.bar.BLOCKED.subkey - if strings.HasPrefix(impactedKey, blockedScope) || strings.HasPrefix(blockedScope, impactedKey) { - return true +// matchesGlobPrefix returns true if and only if the key matches the glob. +// The key is a sequence of string "parts", separated by commas. +// The glob is a sequence of string "patterns". +// matchesGlobPrefix tries to match all of the first K parts to the first K patterns, respectively, +// where K is the length of the shorter of key or glob. +// A pattern matches a part if and only if the pattern is "*" or the lowercase pattern equals the lowercase part. +// +// For example: +// matchesGlobPrefix("foo.bar", []string{"*", "bar", "baz"}) returns true +// matchesGlobPrefix("foo.bar.baz", []string{"*", "bar"}) returns true +// matchesGlobPrefix("foo.bar", []string{"baz", "*"}) returns false +func matchesGlobPrefix(key string, glob []string) bool { + k := strings.Split(key, ".") + for i, g := range glob { + if i >= len(k) { + break + } + if g == "*" { + continue + } + if !strings.EqualFold(k[i], g) { + return false } } - return false + return true } var configShowCmd = &cmds.Command{ @@ -173,7 +180,7 @@ var configShowCmd = &cmds.Command{ NOTE: For security reasons, this command will omit your private key and remote services. If you would like to make a full backup of your config (private key included), you must copy the config file from your repo. `, }, - Type: map[string]interface{}{}, + Type: make(map[string]interface{}), Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { cfgRoot, err := cmdenv.GetConfigRoot(env) if err != nil { @@ -196,12 +203,12 @@ NOTE: For security reasons, this command will omit your private key and remote s return err } - err = scrubValue(cfg, []string{config.IdentityTag, config.PrivKeyTag}) + cfg, err = scrubValue(cfg, []string{config.IdentityTag, config.PrivKeyTag}) if err != nil { return err } - err = scrubOptionalValue(cfg, []string{config.PinningTag, config.RemoteServicesTag}) + cfg, err = scrubOptionalValue(cfg, config.PinningConcealSelector) if err != nil { return err } @@ -222,54 +229,49 @@ NOTE: For security reasons, this command will omit your private key and remote s } // Scrubs value and returns error if missing -func scrubValue(m map[string]interface{}, key []string) error { - return scrub(m, key, false) +func scrubValue(m map[string]interface{}, key []string) (map[string]interface{}, error) { + return scrubMapInternal(m, key, false) } // Scrubs value and returns no error if missing -func scrubOptionalValue(m map[string]interface{}, key []string) error { - return scrub(m, key, true) +func scrubOptionalValue(m map[string]interface{}, key []string) (map[string]interface{}, error) { + return scrubMapInternal(m, key, true) } -func scrub(m map[string]interface{}, key []string, okIfMissing bool) error { - find := func(m map[string]interface{}, k string) (string, interface{}, bool) { - lckey := strings.ToLower(k) - for mkey, val := range m { - lcmkey := strings.ToLower(mkey) - if lckey == lcmkey { - return mkey, val, true - } - } - return "", nil, false +func scrubEither(u interface{}, key []string, okIfMissing bool) (interface{}, error) { + m, ok := u.(map[string]interface{}) + if ok { + return scrubMapInternal(m, key, okIfMissing) } + return scrubValueInternal(m, key, okIfMissing) +} - cur := m - for _, k := range key[:len(key)-1] { - foundk, val, ok := find(cur, k) - if !ok && !okIfMissing { - return errors.New("failed to find specified key") - } - - if foundk != k { - // case mismatch, calling this an error - return fmt.Errorf("case mismatch in config, expected %q but got %q", k, foundk) - } - - mval, mok := val.(map[string]interface{}) - if !mok { - return fmt.Errorf("%s was not a map", foundk) - } - - cur = mval +func scrubValueInternal(v interface{}, key []string, okIfMissing bool) (interface{}, error) { + if v == nil && !okIfMissing { + return nil, errors.New("failed to find specified key") } + return nil, nil +} - todel, _, ok := find(cur, key[len(key)-1]) - if !ok && !okIfMissing { - return fmt.Errorf("%s, not found", strings.Join(key, ".")) +func scrubMapInternal(m map[string]interface{}, key []string, okIfMissing bool) (map[string]interface{}, error) { + if len(key) == 0 { + return make(map[string]interface{}), nil // delete value } - - delete(cur, todel) - return nil + n := map[string]interface{}{} + for k, v := range m { + if key[0] == "*" || strings.EqualFold(key[0], k) { + u, err := scrubEither(v, key[1:], okIfMissing) + if err != nil { + return nil, err + } + if u != nil { + n[k] = u + } + } else { + n[k] = v + } + } + return n, nil } var configEditCmd = &cmds.Command{ @@ -421,7 +423,7 @@ func scrubPrivKey(cfg *config.Config) (map[string]interface{}, error) { return nil, err } - err = scrubValue(cfgMap, []string{config.IdentityTag, config.PrivKeyTag}) + cfgMap, err = scrubValue(cfgMap, []string{config.IdentityTag, config.PrivKeyTag}) if err != nil { return nil, err } @@ -503,14 +505,14 @@ func editConfig(filename string) error { } func replaceConfig(r repo.Repo, file io.Reader) error { - var cfg config.Config - if err := json.NewDecoder(file).Decode(&cfg); err != nil { + var newCfg config.Config + if err := json.NewDecoder(file).Decode(&newCfg); err != nil { return errors.New("failed to decode file as config") } // Handle Identity.PrivKey (secret) - if len(cfg.Identity.PrivKey) != 0 { + if len(newCfg.Identity.PrivKey) != 0 { return errors.New("setting private key with API is not supported") } @@ -524,33 +526,57 @@ func replaceConfig(r repo.Repo, file io.Reader) error { return errors.New("private key in config was not a string") } - cfg.Identity.PrivKey = pkstr + newCfg.Identity.PrivKey = pkstr + + // Handle Pinning.RemoteServices (API.Key of each service is a secret) - // Handle Pinning.RemoteServices (ApiKey of each service is secret) - // Note: these settings are opt-in and may be missing + newServices := newCfg.Pinning.RemoteServices + oldServices, err := getRemotePinningServices(r) + if err != nil { + return fmt.Errorf("failed to load remote pinning services info (%v)", err) + } - if len(cfg.Pinning.RemoteServices) != 0 { - return tryRemoteServiceApiErr + // fail fast if service lists are obviously different + if len(newServices) != len(oldServices) { + return errors.New("cannot add or remove remote pinning services with 'config replace'") } - // detect if existing config has any remote services defined.. - if remoteServicesTag, err := getConfig(r, config.RemoteServicesSelector); err == nil { + // re-apply API details and confirm every modified service already existed + for name, oldSvc := range oldServices { + if newSvc, hadSvc := newServices[name]; hadSvc { + // fail if input changes any of API details + // (interop with config show: allow Endpoint as long it did not change) + if len(newSvc.API.Key) != 0 || (len(newSvc.API.Endpoint) != 0 && newSvc.API.Endpoint != oldSvc.API.Endpoint) { + return errors.New("cannot change remote pinning services api info with `config replace`") + } + // re-apply API details and store service in updated config + newSvc.API = oldSvc.API + newCfg.Pinning.RemoteServices[name] = newSvc + } else { + // error on service rm attempt + return errors.New("cannot add or remove remote pinning services with 'config replace'") + } + } + + return r.SetConfig(&newCfg) +} + +func getRemotePinningServices(r repo.Repo) (map[string]config.RemotePinningService, error) { + var oldServices map[string]config.RemotePinningService + if remoteServicesTag, err := getConfig(r, config.RemoteServicesPath); err == nil { // seems that golang cannot type assert map[string]interface{} to map[string]config.RemotePinningService // so we have to manually copy the data :-| if val, ok := remoteServicesTag.Value.(map[string]interface{}); ok { - var services map[string]config.RemotePinningService jsonString, err := json.Marshal(val) if err != nil { - return fmt.Errorf("failed to replace config while preserving %s: %s", config.RemoteServicesSelector, err) + return nil, err } - err = json.Unmarshal(jsonString, &services) + err = json.Unmarshal(jsonString, &oldServices) if err != nil { - return fmt.Errorf("failed to replace config while preserving %s: %s", config.RemoteServicesSelector, err) + return nil, err } - // .. if so, apply them on top of the new config - cfg.Pinning.RemoteServices = services } } + return oldServices, nil - return r.SetConfig(&cfg) } diff --git a/core/commands/config_test.go b/core/commands/config_test.go new file mode 100644 index 00000000000..9e244f54ff1 --- /dev/null +++ b/core/commands/config_test.go @@ -0,0 +1,17 @@ +package commands + +import "testing" + +func TestScrubMapInternalDelete(t *testing.T) { + m, err := scrubMapInternal(nil, nil, true) + if err != nil { + t.Error(err) + } + if m == nil { + t.Errorf("expecting an empty map, got nil") + } + if len(m) != 0 { + t.Errorf("expecting an empty map, got a non-empty map") + + } +} diff --git a/core/commands/pin/remotepin.go b/core/commands/pin/remotepin.go index 4a1a6d4764a..cd5e0c4288c 100644 --- a/core/commands/pin/remotepin.go +++ b/core/commands/pin/remotepin.go @@ -470,10 +470,11 @@ TIP: } cfg.Pinning.RemoteServices[name] = config.RemotePinningService{ - Api: config.RemotePinningServiceApi{ + API: config.RemotePinningServiceAPI{ Endpoint: endpoint, Key: key, }, + Policies: config.RemotePinningServicePolicies{}, } return repo.SetConfig(cfg) @@ -562,7 +563,7 @@ TIP: pass '--enc=json' for more useful JSON output. services := cfg.Pinning.RemoteServices result := PinServicesList{make([]ServiceDetails, 0, len(services))} for svcName, svcConfig := range services { - svcDetails := ServiceDetails{svcName, svcConfig.Api.Endpoint, nil} + svcDetails := ServiceDetails{svcName, svcConfig.API.Endpoint, nil} // if --pin-count is passed, we try to fetch pin numbers from remote service if req.Options[pinServiceStatOptionName].(bool) { @@ -738,11 +739,11 @@ func getRemotePinServiceInfo(env cmds.Environment, name string) (endpoint, key s if !present { return "", "", fmt.Errorf("service not known") } - endpoint, err = normalizeEndpoint(service.Api.Endpoint) + endpoint, err = normalizeEndpoint(service.API.Endpoint) if err != nil { return "", "", err } - return endpoint, service.Api.Key, nil + return endpoint, service.API.Key, nil } func normalizeEndpoint(endpoint string) (string, error) { diff --git a/go.mod b/go.mod index ff350c01840..ea8bc630ffc 100644 --- a/go.mod +++ b/go.mod @@ -32,7 +32,7 @@ require ( github.com/ipfs/go-ipfs-blockstore v0.1.4 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.11.0 + github.com/ipfs/go-ipfs-config v0.12.0 github.com/ipfs/go-ipfs-ds-help v0.1.1 github.com/ipfs/go-ipfs-exchange-interface v0.0.1 github.com/ipfs/go-ipfs-exchange-offline v0.0.1 diff --git a/go.sum b/go.sum index 50ca112faed..87a6d822328 100644 --- a/go.sum +++ b/go.sum @@ -329,8 +329,8 @@ github.com/ipfs/go-ipfs-chunker v0.0.5 h1:ojCf7HV/m+uS2vhUGWcogIIxiO5ubl5O57Q7Na 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.11.0 h1:w4t2pz415Gtg6MTUKAq06C7ezC59/Us+k3+n1Tje+wg= -github.com/ipfs/go-ipfs-config v0.11.0/go.mod h1:Ei/FLgHGTdPyqCPK0oPCwGTe8VSnsjJjx7HZqUb6Ry0= +github.com/ipfs/go-ipfs-config v0.12.0 h1:wxqN3ohBlis1EkhkzIKuF+XLx4YNn9rNpiSOYw3DFZc= +github.com/ipfs/go-ipfs-config v0.12.0/go.mod h1:Ei/FLgHGTdPyqCPK0oPCwGTe8VSnsjJjx7HZqUb6Ry0= 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= diff --git a/test/sharness/t0700-remotepin.sh b/test/sharness/t0700-remotepin.sh index cac374193ad..1aeb7a3ec39 100755 --- a/test/sharness/t0700-remotepin.sh +++ b/test/sharness/t0700-remotepin.sh @@ -34,7 +34,8 @@ test_expect_success "creating test user on remote pinning service" ' ipfs pin remote service add test_pin_svc ${TEST_PIN_SVC} ${TEST_PIN_SVC_KEY} && ipfs pin remote service add test_invalid_key_svc ${TEST_PIN_SVC} fake_api_key && ipfs pin remote service add test_invalid_url_path_svc ${TEST_PIN_SVC}/invalid-path fake_api_key && - ipfs pin remote service add test_invalid_url_dns_svc https://invalid-service.example.com fake_api_key + ipfs pin remote service add test_invalid_url_dns_svc https://invalid-service.example.com fake_api_key && + ipfs pin remote service add test_pin_mfs_svc ${TEST_PIN_SVC} ${TEST_PIN_SVC_KEY} ' # add a service with a invalid endpoint @@ -51,23 +52,60 @@ test_expect_success "test 'ipfs pin remote service ls'" ' grep -q test_invalid_url_dns_svc ls_out ' -# SECURITY of access tokens in Api.Key fields: -# Pinning.RemoteServices includes Api.Key, and we give it the same treatment +test_expect_success "test enabling mfs pinning" ' + ipfs config --json Pinning.RemoteServices.test_pin_mfs_svc.Policies.MFS.RepinInterval \"10s\" && + ipfs config --json Pinning.RemoteServices.test_pin_mfs_svc.Policies.MFS.PinName \"mfs_test_pin\" && + ipfs config --json Pinning.RemoteServices.test_pin_mfs_svc.Policies.MFS.Enable true && + ipfs config --json Pinning.RemoteServices.test_pin_mfs_svc.Policies.MFS.RepinInterval > repin_interval && + ipfs config --json Pinning.RemoteServices.test_pin_mfs_svc.Policies.MFS.PinName > pin_name && + ipfs config --json Pinning.RemoteServices.test_pin_mfs_svc.Policies.MFS.Enable > enable && + echo 10s > expected_repin_interval && + echo mfs_test_pin > expected_pin_name && + echo true > expected_enable && + test_cmp repin_interval expected_repin_interval && + test_cmp pin_name expected_pin_name && + test_cmp enable expected_enable +' + +# expect PIN to be created +test_expect_success "verify MFS root is being pinned" ' + ipfs files cp /ipfs/bafkqaaa /mfs-pinning-test-$(date +%s.%N) && + ipfs files flush && + sleep 31 && + ipfs files stat / --enc=json | jq -r .Hash > mfs_cid && + ipfs pin remote ls --service=test_pin_mfs_svc --name=mfs_test_pin --status=queued,pinning,pinned,failed --enc=json | tee ls_out | jq -r .Cid > pin_cid && + cat mfs_cid ls_out && + test_cmp mfs_cid pin_cid +' + +# expect existing PIN to be replaced +test_expect_success "verify MFS root is being repinned on CID change" ' + ipfs files cp /ipfs/bafkqaaa /mfs-pinning-repin-test-$(date +%s.%N) && + ipfs files flush && + sleep 31 && + ipfs files stat / --enc=json | jq -r .Hash > mfs_cid && + ipfs pin remote ls --service=test_pin_mfs_svc --name=mfs_test_pin --status=queued,pinning,pinned,failed --enc=json | tee ls_out | jq -r .Cid > pin_cid && + cat mfs_cid ls_out && + test_cmp mfs_cid pin_cid +' + +# SECURITY of access tokens in API.Key fields: +# Pinning.RemoteServices includes API.Key, and we give it the same treatment # as Identity.PrivKey to prevent exposing it on the network test_expect_success "'ipfs config Pinning' fails" ' test_expect_code 1 ipfs config Pinning 2>&1 > config_out ' -test_expect_success "output does not include Api.Key" ' +test_expect_success "output does not include API.Key" ' test_expect_code 1 grep -q Key config_out ' -test_expect_success "'ipfs config Pinning.RemoteServices.test_pin_svc.Api.Key' fails" ' - test_expect_code 1 ipfs config Pinning.RemoteServices.test_pin_svc.Api.Key 2> config_out +test_expect_success "'ipfs config Pinning.RemoteServices.test_pin_svc.API.Key' fails" ' + test_expect_code 1 ipfs config Pinning.RemoteServices.test_pin_svc.API.Key 2> config_out ' test_expect_success "output includes meaningful error" ' - echo "Error: cannot show or change pinning services through this API (try: ipfs pin remote service --help)" > config_exp && + echo "Error: cannot show or change pinning services credentials" > config_exp && test_cmp config_exp config_out ' @@ -78,29 +116,30 @@ test_expect_success "output includes meaningful error" ' test_cmp config_exp config_out ' -test_expect_success "'ipfs config show' doesn't include RemoteServices" ' - ipfs config show > show_config && - test_expect_code 1 grep RemoteServices show_config +test_expect_success "'ipfs config show' does not include Pinning.RemoteServices[*].API.Key" ' + ipfs config show | tee show_config | jq -r .Pinning.RemoteServices > remote_services && + test_expect_code 1 grep \"Key\" remote_services && + test_expect_code 1 grep fake_api_key show_config && + test_expect_code 1 grep "$TEST_PIN_SVC_KEY" show_config ' -test_expect_success "'ipfs config replace' injects remote services back" ' - test_expect_code 1 grep -q -E "test_.+_svc" show_config && +test_expect_success "'ipfs config replace' injects Pinning.RemoteServices[*].API.Key back" ' + test_expect_code 1 grep fake_api_key show_config && + test_expect_code 1 grep "$TEST_PIN_SVC_KEY" show_config && ipfs config replace show_config && - test_expect_code 0 grep -q test_pin_svc "$IPFS_PATH/config" && - test_expect_code 0 grep -q test_invalid_key_svc "$IPFS_PATH/config" && - test_expect_code 0 grep -q test_invalid_url_path_svc "$IPFS_PATH/config" && - test_expect_code 0 grep -q test_invalid_url_dns_svc "$IPFS_PATH/config" + test_expect_code 0 grep fake_api_key "$IPFS_PATH/config" && + test_expect_code 0 grep "$TEST_PIN_SVC_KEY" "$IPFS_PATH/config" ' # note: we remove Identity.PrivKey to ensure error is triggered by Pinning.RemoteServices -test_expect_success "'ipfs config replace' with remote services errors out" ' - jq -M "del(.Identity.PrivKey)" "$IPFS_PATH/config" | jq ".Pinning += { RemoteServices: {\"foo\": {} }}" > new_config && +test_expect_success "'ipfs config replace' with Pinning.RemoteServices[*].API.Key errors out" ' + jq -M "del(.Identity.PrivKey)" "$IPFS_PATH/config" | jq ".Pinning += { RemoteServices: {\"myservice\": {\"API\": {\"Endpoint\": \"https://example.com/psa\", \"Key\": \"mysecret\"}}}}" > new_config && test_expect_code 1 ipfs config replace - < new_config 2> replace_out ' -test_expect_success "output includes meaningful error" ' - echo "Error: cannot show or change pinning services through this API (try: ipfs pin remote service --help)" > replace_expected && +test_expect_success "output includes meaningful error" " + echo \"Error: cannot add or remove remote pinning services with 'config replace'\" > replace_expected && test_cmp replace_out replace_expected -' +" # /SECURITY From 884a5aebd748336db963e91daf7b916054486a99 Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Thu, 28 Jan 2021 21:42:55 -0500 Subject: [PATCH 107/116] update distpath to version with fs-repo-migrations v1.7.1 --- repo/fsrepo/migrations/migrations.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repo/fsrepo/migrations/migrations.go b/repo/fsrepo/migrations/migrations.go index ad94b04a652..33266dd9127 100644 --- a/repo/fsrepo/migrations/migrations.go +++ b/repo/fsrepo/migrations/migrations.go @@ -15,7 +15,7 @@ import ( "strings" ) -var DistPath = "https://ipfs.io/ipfs/QmahS3i7MkjVVDjPs6CoPhCKGi27LkHGXrzQ45jCRX6wcK" +var DistPath = "https://ipfs.io/ipfs/QmYRLRDKobvg1AXTGeK5Xk6ntWTsjGiHbyNKhWfz7koGpa" func init() { if dist := os.Getenv("IPFS_DIST_PATH"); dist != "" { From 4080333de16ff06eaa0c0d74e461e370a038ffcd Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Thu, 28 Jan 2021 23:46:00 -0500 Subject: [PATCH 108/116] Release v0.8.0-rc2 --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index 6e2116f6b6e..ccaa3b73c02 100644 --- a/version.go +++ b/version.go @@ -4,7 +4,7 @@ package ipfs var CurrentCommit string // CurrentVersionNumber is the current application's version literal -const CurrentVersionNumber = "0.8.0-rc1" +const CurrentVersionNumber = "0.8.0-rc2" const ApiVersion = "/go-ipfs/" + CurrentVersionNumber + "/" From 9b8308dc070d214e0d1bfbab1dfea5b61ec5ad67 Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Thu, 18 Feb 2021 16:44:16 -0500 Subject: [PATCH 109/116] update deps * Update some go libraries to pull in bug fixes. This will fix the s3 plugin. See https://github.com/ipfs/go-ds-s3/pull/146. * Update other libraries for more bug fixes. This is intentionally minimal as I'm filing it against the release branch. --- go.mod | 6 +++--- go.sum | 11 +++++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 25e25fcd3d5..3f627c024f5 100644 --- a/go.mod +++ b/go.mod @@ -105,10 +105,10 @@ require ( go.opencensus.io v0.22.5 go.uber.org/fx v1.13.1 go.uber.org/zap v1.16.0 - golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a + golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect - golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 - golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f + golang.org/x/sync v0.0.0-20201207232520-09787c993a3a + golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c ) go 1.14 diff --git a/go.sum b/go.sum index dcb0966c873..93e69fbee5a 100644 --- a/go.sum +++ b/go.sum @@ -1097,6 +1097,8 @@ golang.org/x/crypto v0.0.0-20200423211502-4bdfaf469ed5/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY= +golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= 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= @@ -1180,6 +1182,9 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 h1:qwRHBd0NqMbJxfbotnDhm2By golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/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 h1:DcqTD9SDLc+1P/r1EmRBwnVsrOwW+kk2vWf9n+1sGhs= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 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= @@ -1227,6 +1232,11 @@ golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 h1:ogLJMz+qpzav7lGMh10LMvAkM golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c h1:VwygUrnw9jn88c4u8GD3rZQbqrP/tgas88tPUbBxQrk= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221 h1:/ZHdbVpdR/jk3g30/d4yUL0JU9kksj8+F/bnQUVLGDM= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= 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= @@ -1277,6 +1287,7 @@ golang.org/x/tools v0.0.0-20200827010519-17fd2f27a9e3 h1:r3P/5xOq/dK1991B65Oy6E1 golang.org/x/tools v0.0.0-20200827010519-17fd2f27a9e3/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a h1:CB3a9Nez8M13wwlr/E2YtwoU+qYHKfC+JrDa45RXXoQ= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc= 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= From 5e330b2806253961cb88d005fdc24e6d5c59e312 Mon Sep 17 00:00:00 2001 From: gammazero Date: Tue, 16 Feb 2021 14:41:03 -0800 Subject: [PATCH 110/116] Fix build issue with go1.16 --- go.sum | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/go.sum b/go.sum index 93e69fbee5a..0b5542e5b70 100644 --- a/go.sum +++ b/go.sum @@ -167,7 +167,6 @@ github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5x github.com/gogo/protobuf v1.1.1/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= @@ -457,7 +456,6 @@ github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfV github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= 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 h1:reN85Pxc5larApoH1keMBiu2GWtPqXQ1nc9gx+jOU+E= 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= @@ -619,7 +617,6 @@ github.com/libp2p/go-libp2p-pnet v0.2.0 h1:J6htxttBipJujEjz1y0a5+eYoiPcFHhSYHH6n 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 h1:YNVRyXqBgv9i4RG88jzoTtkSOaSB45CqHkL29NNBZb4= github.com/libp2p/go-libp2p-pubsub v0.4.0/go.mod h1:izkeMLvz6Ht8yAISXjx60XUQZMq9ZMe5h2ih4dLIBIQ= github.com/libp2p/go-libp2p-pubsub v0.4.1 h1:j4umIg5nyus+sqNfU+FWvb9aeYFQH/A+nDFhWj+8yy8= github.com/libp2p/go-libp2p-pubsub v0.4.1/go.mod h1:izkeMLvz6Ht8yAISXjx60XUQZMq9ZMe5h2ih4dLIBIQ= @@ -990,7 +987,6 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf 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 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -1095,7 +1091,6 @@ golang.org/x/crypto v0.0.0-20200117160349-530e935923ad/go.mod h1:LzIPMQfyMNhhGPh 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-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= @@ -1158,7 +1153,6 @@ golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/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 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= @@ -1178,9 +1172,7 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 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 h1:qwRHBd0NqMbJxfbotnDhm2ByMI1Shq4Y6oRJo21SGJA= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/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 h1:DcqTD9SDLc+1P/r1EmRBwnVsrOwW+kk2vWf9n+1sGhs= @@ -1228,9 +1220,7 @@ golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 h1:ogLJMz+qpzav7lGMh10LMvAkM/fAoGlaiiHYiFYdm80= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c h1:VwygUrnw9jn88c4u8GD3rZQbqrP/tgas88tPUbBxQrk= @@ -1283,14 +1273,11 @@ golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapK 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-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200827010519-17fd2f27a9e3 h1:r3P/5xOq/dK1991B65Oy6E1fRF/2d/fSYZJ/fXGVfJc= golang.org/x/tools v0.0.0-20200827010519-17fd2f27a9e3/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a h1:CB3a9Nez8M13wwlr/E2YtwoU+qYHKfC+JrDa45RXXoQ= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc= 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 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From a40cbb03e1ae07d932b3dc93a5d274fb91458590 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Mon, 15 Feb 2021 19:47:41 +0100 Subject: [PATCH 111/116] docs: Pinning.RemoteServices.Policies (cherry picked from commit c338ed83c7a8e7b9e4e679837a6771f8611abb15) --- docs/config.md | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/docs/config.md b/docs/config.md index d2806a8a7d0..5d700051ceb 100644 --- a/docs/config.md +++ b/docs/config.md @@ -181,6 +181,8 @@ does (e.g, `"1d2h4m40.01s"`). - [`Pinning.RemoteServices.API`](#pinningremoteservices-api) - [`Pinning.RemoteServices.API.Endpoint`](#pinningremoteservices-apiendpoint) - [`Pinning.RemoteServices.API.Key`](#pinningremoteservices-apikey) + - [`Pinning.RemoteServices.Policies`](#pinningremoteservices-policies) + - [`Pinning.RemoteServices.Policies.MFS`](#pinningremoteservices-policiesmfs) - [`Pubsub`](#pubsub) - [`Pubsub.Router`](#pubsubrouter) - [`Pubsub.DisableSigning`](#pubsubdisablesigning) @@ -847,7 +849,7 @@ Example: "API" : { "Endpoint" : "https://pinningservice.tld:1234/my/api/path", "Key" : "someOpaqueKey" - } + } } } } @@ -868,6 +870,44 @@ The key through which access to the pinning service is granted Type: `string` +#### `Pinning.RemoteServices: Policies` + +Contains additional opt-in policies for the remote pinning service + +##### `Pinning.RemoteServices: Policies.MFS` + +When this policy is enabled it will be following changes to MFS +and updating the pin for MFS root on the configured remote service. + +Pin request to the remote service is sent only when MFS root changed +and time passed since the previous pin is bigger than `RepinInterval`. + +###### `Pinning.RemoteServices: Policies.MFS.Enabled` + +Controls if this policy is active. + +Default: `false` + +Type: `bool` + +###### `Pinning.RemoteServices: Policies.MFS.PinName` + +Optional name to use for remote pin that represents MFS root CID. +When left empty, default name will be generated. + +Default: `"policy/12.../mfs"` + +Type: `string` + +###### `Pinning.RemoteServices: Policies.MFS.RepinInterval` + +Defines how often (at most) the pin request should be sent to remote service. +When left empty, default interval will be used. Values lower than `1m` will be ignored. + +Default: `"5m"` + +Type: `duration` + ## `Pubsub` Pubsub configures the `ipfs pubsub` subsystem. To use, it must be enabled by From e29ae2e737a9f92f78ebb565457376b3712f40ca Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Mon, 15 Feb 2021 20:03:44 +0100 Subject: [PATCH 112/116] style: improved MFS PinName example Co-authored-by: Adin Schmahmann (cherry picked from commit af96ded9734b728d1bee21bcfb7e7f40deebe4c0) --- docs/config.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/config.md b/docs/config.md index 5d700051ceb..c68355cc409 100644 --- a/docs/config.md +++ b/docs/config.md @@ -895,7 +895,7 @@ Type: `bool` Optional name to use for remote pin that represents MFS root CID. When left empty, default name will be generated. -Default: `"policy/12.../mfs"` +Default: `"policy/{PeerID}/mfs"`, e.g. `"policy/12.../mfs"` Type: `string` From 94dd4be8f8fd074ca2a48734501b4b2332b629a9 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Mon, 15 Feb 2021 21:28:14 +0100 Subject: [PATCH 113/116] style: docs/config.md Co-authored-by: Jessica Schilling (cherry picked from commit aaa64baaed2a032036242768c4088647cfb59d20) --- docs/config.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/config.md b/docs/config.md index c68355cc409..e4077726891 100644 --- a/docs/config.md +++ b/docs/config.md @@ -872,15 +872,15 @@ Type: `string` #### `Pinning.RemoteServices: Policies` -Contains additional opt-in policies for the remote pinning service +Contains additional opt-in policies for the remote pinning service. ##### `Pinning.RemoteServices: Policies.MFS` -When this policy is enabled it will be following changes to MFS -and updating the pin for MFS root on the configured remote service. +When this policy is enabled, it follows changes to MFS +and updates the pin for MFS root on the configured remote service. -Pin request to the remote service is sent only when MFS root changed -and time passed since the previous pin is bigger than `RepinInterval`. +A pin request to the remote service is sent only when MFS root has changed +and time has passed, since the previous pin is bigger than `RepinInterval`. ###### `Pinning.RemoteServices: Policies.MFS.Enabled` @@ -892,8 +892,8 @@ Type: `bool` ###### `Pinning.RemoteServices: Policies.MFS.PinName` -Optional name to use for remote pin that represents MFS root CID. -When left empty, default name will be generated. +Optional name to use for a remote pin that represents the MFS root CID. +When left empty, a default name will be generated. Default: `"policy/{PeerID}/mfs"`, e.g. `"policy/12.../mfs"` @@ -901,8 +901,8 @@ Type: `string` ###### `Pinning.RemoteServices: Policies.MFS.RepinInterval` -Defines how often (at most) the pin request should be sent to remote service. -When left empty, default interval will be used. Values lower than `1m` will be ignored. +Defines how often (at most) the pin request should be sent to the remote service. +If left empty, the default interval will be used. Values lower than `1m` will be ignored. Default: `"5m"` From 3d8321ab2e06b3705a497ad3f3168c24b5904c5f Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Mon, 15 Feb 2021 21:52:32 +0100 Subject: [PATCH 114/116] docs: RepinInterval (cherry picked from commit 04838257f8cfee9ca783c5f0f4d0c795e941c818) --- docs/config.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/config.md b/docs/config.md index e4077726891..bf244ecf2dd 100644 --- a/docs/config.md +++ b/docs/config.md @@ -879,8 +879,8 @@ Contains additional opt-in policies for the remote pinning service. When this policy is enabled, it follows changes to MFS and updates the pin for MFS root on the configured remote service. -A pin request to the remote service is sent only when MFS root has changed -and time has passed, since the previous pin is bigger than `RepinInterval`. +A pin request to the remote service is sent only when MFS root CID has changed +and enough time has passed since the previous request (determined by `RepinInterval`). ###### `Pinning.RemoteServices: Policies.MFS.Enabled` From 9a20c9ebf22b08139f1a2bca8657bfddd3cd52c5 Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Thu, 18 Feb 2021 16:58:12 -0500 Subject: [PATCH 115/116] Release v0.8.0 --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index ccaa3b73c02..2b8c4f93151 100644 --- a/version.go +++ b/version.go @@ -4,7 +4,7 @@ package ipfs var CurrentCommit string // CurrentVersionNumber is the current application's version literal -const CurrentVersionNumber = "0.8.0-rc2" +const CurrentVersionNumber = "0.8.0" const ApiVersion = "/go-ipfs/" + CurrentVersionNumber + "/" From 30fa364b516a7e333d21510eaa9446c740d7a21a Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Thu, 18 Feb 2021 17:52:41 -0500 Subject: [PATCH 116/116] update CHANGELOG for v0.8.0 --- CHANGELOG.md | 560 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 560 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 63382740f89..b2807e20f17 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,565 @@ # go-ipfs changelog +## v0.8.0 2021-02-18 + +We're happy to announce go-ipfs 0.8.0! This is planned to be a fairly small release focused on integrating in the new pinning service/remote pinning [API](https://github.com/ipfs/pinning-services-api-spec) that makes the experience of managing pins across pinning services easier and more uniform. + +### 🔦 Highlights + +#### 🧷 Remote pinning services + +There is now support for asking remote services to pin data for you. This means anyone can implement the [spec](https://ipfs.github.io/pinning-services-api-spec/) (developed in this [repo](https://github.com/ipfs/pinning-services-api-spec)) and allow for pin management. + +All of the CLI (and corresponding HTTP API) commands are available under `ipfs pin remote`. + +This remote pinning service comes with a redesign of how we're thinking about pinning and includes some commonly requested features such as: +- Pins can have names (and coming soon metadata) +- The same content can be pinned multiple times, but of course stored only once + - This allows applications using the same pinning service to manage their own pins without worrying about removing content important to another application +- Data can be pinned in either the foreground or background + + +Examples include: +``` +ipfs pin remote service add myservice https://myservice.tld:1234/api/path myaccess key + +ipfs pin remote add /ipfs/bafymydata --service=myservice --name=myfile +ipfs pin remote ls --service=myservice --name=myfile +ipfs pin remote ls --service=myservice --cid=bafymydata +ipfs pin remote rm --serivce=myservice --name=myfile +``` +A few notes: + +Remote pinning services work with recursive pins. This means commands like `ipfs pin remote ls` will not list indirectly pinned CIDs. + +While pinning service data is stored in the configuration file it cannot be edited directly via the `ipfs config` commands due to the sensitive nature of pinning service API keys. The `ipfs pin remote service` commands can be used for interacting with remote service settings. + +#### 📌 Faster local pinning and unpinning + +The pinning subsystem has been redesigned to be much faster and more flexible in how it tracks pins. For users who are working with many pins this will lead to a big speed increase in listing and modifying the set of pinned items as well as decreased memory usage. + +Part of the redesign was setup to account for being able to interact with local pins the same way we can now interact with remote pins (e.g. names, being allowed to pin the same CID multiple times, etc.). Keep posted for more improvements to pinning. + +#### DNSLink names on https:// subdomains + +Previously DNSLink names would have trouble loading over subdomain gateways with HTTPS support since there is no way to get multilevel wildcard certificates (e.g. `en.wikipedia-on-ipfs.org.ipns.dweb.link` cannot be covered by `*.ipns.dweb.link`). Therefore, when trying to load DNSLink names over https:// subdomains go-ipfs we now forward to an encoded DNS name. Since DNS names cannot contain `.` in them they are escaped using `-`. + +`/ipns/en.wikipedia-on-ipfs.org` → +`ipns://en.wikipedia-on-ipfs.org` → +`https://dweb.link/ipns/en.wikipedia-on-ipfs.org` +`https://en-wikipedia--on--ipfs-org.ipns.dweb.link` :point_left: _a single DNS label, no TLS error_ + +#### QUIC update + +QUIC support has received a number of upgrades, including the ability to take advantage of larger UDP receive buffers for increased performance. + +Linux users may notice a logged error on daemon startup if your system needs extra configuration to allow IPFS increase the buffer size. A helpful link for resolving this is in the log message as well as [here](https://github.com/lucas-clemente/quic-go/wiki/UDP-Receive-Buffer-Size). + +#### 👋 No more Darwin 386 builds + +Go 1.15 (the latest version of Go) [no longer supports](https://github.com/golang/go/issues/34749) Darwin 386 and so we are dropping support as well. + +### Changelog + +- github.com/ipfs/go-ipfs: + - Release v0.8.0 + - docs: RepinInterval + - style: docs/config.md + - style: improved MFS PinName example + - docs: Pinning.RemoteServices.Policies + - fix: decrease log level of opencensus initialization ([ipfs/go-ipfs#7815](https://github.com/ipfs/go-ipfs/pull/7815)) + - Register oc metrics ([ipfs/go-ipfs#7593](https://github.com/ipfs/go-ipfs/pull/7593)) + - add remote pinning to ipfs command (#7661) ([ipfs/go-ipfs#7661](https://github.com/ipfs/go-ipfs/pull/7661)) + - More p2p proxy checks ([ipfs/go-ipfs#7797](https://github.com/ipfs/go-ipfs/pull/7797)) + - Use datastore based pinning ([ipfs/go-ipfs#7750](https://github.com/ipfs/go-ipfs/pull/7750)) + - fix: return an error when an unknown object type is passed ([ipfs/go-ipfs#7795](https://github.com/ipfs/go-ipfs/pull/7795)) + - clarify why ipfs file ls is being deprecated ([ipfs/go-ipfs#7755](https://github.com/ipfs/go-ipfs/pull/7755)) + - fix: ipfs dag export uses the CoreAPI and respects the offline flag ([ipfs/go-ipfs#7753](https://github.com/ipfs/go-ipfs/pull/7753)) + - return an error when trying to download fs-repo-migrations for linux + musl ([ipfs/go-ipfs#7735](https://github.com/ipfs/go-ipfs/pull/7735)) + - fix: do not create a new (unused) peerID when initializing from config ([ipfs/go-ipfs#7730](https://github.com/ipfs/go-ipfs/pull/7730)) + - docs: Add a link in config.md ([ipfs/go-ipfs#7780](https://github.com/ipfs/go-ipfs/pull/7780)) + - update libp2p for stream closure refactor ([ipfs/go-ipfs#7747](https://github.com/ipfs/go-ipfs/pull/7747)) + - Fix typo in ipfs dag stat command ([ipfs/go-ipfs#7761](https://github.com/ipfs/go-ipfs/pull/7761)) + - docs(readme): key rotation in docker (#7721) ([ipfs/go-ipfs#7721](https://github.com/ipfs/go-ipfs/pull/7721)) + - fix(dnslink-gw): breadcrumbs and CID column when dir listing ([ipfs/go-ipfs#7699](https://github.com/ipfs/go-ipfs/pull/7699)) + - fix(gw): preserve query on website redirect ([ipfs/go-ipfs#7727](https://github.com/ipfs/go-ipfs/pull/7727)) + - feat: ipfs-webui v2.11.4 ([ipfs/go-ipfs#7716](https://github.com/ipfs/go-ipfs/pull/7716)) + - docs: how the ipfs snap is built and published ([ipfs/go-ipfs#7725](https://github.com/ipfs/go-ipfs/pull/7725)) + - fix: webui on ipv6 localhost ([ipfs/go-ipfs#7731](https://github.com/ipfs/go-ipfs/pull/7731)) + - Add missing plugin support on FreeBSD ([ipfs/go-ipfs#7722](https://github.com/ipfs/go-ipfs/pull/7722)) + - fix error when computing coverage ([ipfs/go-ipfs#7726](https://github.com/ipfs/go-ipfs/pull/7726)) + - docs(config): X-Forwarded-Host ([ipfs/go-ipfs#7651](https://github.com/ipfs/go-ipfs/pull/7651)) + - chore: webui v2.11.2 ([ipfs/go-ipfs#7703](https://github.com/ipfs/go-ipfs/pull/7703)) + - Add task for updating CLI docs right after updating the HTTP-api docs ([ipfs/go-ipfs#7711](https://github.com/ipfs/go-ipfs/pull/7711)) + - feat(gateway): Content-Disposition improvements ([ipfs/go-ipfs#7677](https://github.com/ipfs/go-ipfs/pull/7677)) + - fix build on Plan 9 ([ipfs/go-ipfs#7690](https://github.com/ipfs/go-ipfs/pull/7690)) + - docs: update changelog for v0.7.0 + - chore: bump webui version + - fix: remove the (empty) alias for --peerid-base + - fix: use override GOFLAGS changes from 480defab689610550ee3d346e31441a2bb881fcb but keep trimpath usage as is + - Revert "fix: override GOFLAGS" + - Fix --ipns-base alias ([ipfs/go-ipfs#7659](https://github.com/ipfs/go-ipfs/pull/7659)) + - docs: update config to indicate SECIO deprecation ([ipfs/go-ipfs#7630](https://github.com/ipfs/go-ipfs/pull/7630)) + - fix: ipfs dht put/get commands with peerIDs encoded as CIDs ([ipfs/go-ipfs#7633](https://github.com/ipfs/go-ipfs/pull/7633)) + - update version to 0.8.0-dev ([ipfs/go-ipfs#7629](https://github.com/ipfs/go-ipfs/pull/7629)) +- github.com/ipfs/go-bitswap (v0.2.20 -> v0.3.3): + - feat: configurable engine blockstore worker count (#449) ([ipfs/go-bitswap#449](https://github.com/ipfs/go-bitswap/pull/449)) + - fix: set the score ledger on start ([ipfs/go-bitswap#447](https://github.com/ipfs/go-bitswap/pull/447)) + - feat: update for go-libp2p-core 0.7.0 interface changes ([ipfs/go-bitswap#445](https://github.com/ipfs/go-bitswap/pull/445)) + - fix: guard access to the mock wiretap with a lock ([ipfs/go-bitswap#446](https://github.com/ipfs/go-bitswap/pull/446)) + - Add WireTap interface (#444) ([ipfs/go-bitswap#444](https://github.com/ipfs/go-bitswap/pull/444)) + - Fix: Increment stats.MessagesSent in msgToStream() function (#441) ([ipfs/go-bitswap#441](https://github.com/ipfs/go-bitswap/pull/441)) + - refactor: remove extraneous ledger field init (#437) ([ipfs/go-bitswap#437](https://github.com/ipfs/go-bitswap/pull/437)) + - Added `WithScoreLedger` Bitswap option (#430) ([ipfs/go-bitswap#430](https://github.com/ipfs/go-bitswap/pull/430)) +- github.com/ipfs/go-blockservice (v0.1.3 -> v0.1.4): + - Avoid modifying passed in slice of cids ([ipfs/go-blockservice#65](https://github.com/ipfs/go-blockservice/pull/65)) +- github.com/ipfs/go-ds-badger (v0.2.4 -> v0.2.6): + - Log error if batch not committed or canceled ([ipfs/go-ds-badger#108](https://github.com/ipfs/go-ds-badger/pull/108)) + - Add Cancel function; add finalizer to cleanup abandoned batch ([ipfs/go-ds-badger#105](https://github.com/ipfs/go-ds-badger/pull/105)) + - Do not implement batches using transactions ([ipfs/go-ds-badger#104](https://github.com/ipfs/go-ds-badger/pull/104)) + - readme: add information on Badger2 datastore ([ipfs/go-ds-badger#102](https://github.com/ipfs/go-ds-badger/pull/102)) + - update contributing link ([ipfs/go-ds-badger#91](https://github.com/ipfs/go-ds-badger/pull/91)) + - Use current go-log (#89) ([ipfs/go-ds-badger#89](https://github.com/ipfs/go-ds-badger/pull/89)) +- github.com/ipfs/go-graphsync (v0.1.1 -> v0.6.0): + - docs(CHANGELOG): revise for 0.6.0 + - Merge branch 'master' into release/v0.6.0 + - docs(CHANGELOG): update for 0.6.0 release + - move block allocation into message queue (#140) ([ipfs/go-graphsync#140](https://github.com/ipfs/go-graphsync/pull/140)) + - Response Assembler Refactor (#138) ([ipfs/go-graphsync#138](https://github.com/ipfs/go-graphsync/pull/138)) + - Add error listener on receiver (#136) ([ipfs/go-graphsync#136](https://github.com/ipfs/go-graphsync/pull/136)) + - Run testplan on in CI (#137) ([ipfs/go-graphsync#137](https://github.com/ipfs/go-graphsync/pull/137)) + - fix(responsemanager): fix network error propogation (#133) ([ipfs/go-graphsync#133](https://github.com/ipfs/go-graphsync/pull/133)) + - testground test for graphsync (#132) ([ipfs/go-graphsync#132](https://github.com/ipfs/go-graphsync/pull/132)) + - docs(CHANGELOG): update for v0.5.2 ([ipfs/go-graphsync#130](https://github.com/ipfs/go-graphsync/pull/130)) + - RegisterNetworkErrorListener should fire when there's an error connecting to the peer (#127) ([ipfs/go-graphsync#127](https://github.com/ipfs/go-graphsync/pull/127)) + - Permit multiple data subscriptions per original topic (#128) ([ipfs/go-graphsync#128](https://github.com/ipfs/go-graphsync/pull/128)) + - release: v0.5.1 (#123) ([ipfs/go-graphsync#123](https://github.com/ipfs/go-graphsync/pull/123)) + - feat(responsemanager): allow configuration of max requests (#122) ([ipfs/go-graphsync#122](https://github.com/ipfs/go-graphsync/pull/122)) + - docs(CHANGELOG): update for 0.5.0 ([ipfs/go-graphsync#120](https://github.com/ipfs/go-graphsync/pull/120)) + - feat: use go-libp2p-core 0.7.0 stream interfaces (#116) ([ipfs/go-graphsync#116](https://github.com/ipfs/go-graphsync/pull/116)) + - Merge branch 'release/v0.4.3' + - chore(benchmarks): remove extra files + - fix(peerresponsemanager): avoid race condition that could result in NPE in link tracker (#118) ([ipfs/go-graphsync#118](https://github.com/ipfs/go-graphsync/pull/118)) + - docs(CHANGELOG): update for 0.4.2 ([ipfs/go-graphsync#117](https://github.com/ipfs/go-graphsync/pull/117)) + - feat(memory): improve memory usage (#110) ([ipfs/go-graphsync#110](https://github.com/ipfs/go-graphsync/pull/110)) + - fix(notifications): fix lock in close (#115) ([ipfs/go-graphsync#115](https://github.com/ipfs/go-graphsync/pull/115)) + - docs(CHANGELOG): update for v0.4.1 ([ipfs/go-graphsync#114](https://github.com/ipfs/go-graphsync/pull/114)) + - fix(allocator): remove peer from peer status list + - docs(CHANGELOG): update for v0.4.0 + - docs(CHANGELOG): update for 0.3.1 ([ipfs/go-graphsync#112](https://github.com/ipfs/go-graphsync/pull/112)) + - Add allocator for memory backpressure (#108) ([ipfs/go-graphsync#108](https://github.com/ipfs/go-graphsync/pull/108)) + - Shutdown notifications go routines (#109) ([ipfs/go-graphsync#109](https://github.com/ipfs/go-graphsync/pull/109)) + - Switch to google protobuf generator (#105) ([ipfs/go-graphsync#105](https://github.com/ipfs/go-graphsync/pull/105)) + - feat(CHANGELOG): update for 0.3.0 ([ipfs/go-graphsync#104](https://github.com/ipfs/go-graphsync/pull/104)) + - docs(CHANGELOG): update for 0.2.1 ([ipfs/go-graphsync#103](https://github.com/ipfs/go-graphsync/pull/103)) + - Track actual network operations in a response (#102) ([ipfs/go-graphsync#102](https://github.com/ipfs/go-graphsync/pull/102)) + - feat(responsecache): prune blocks more intelligently (#101) ([ipfs/go-graphsync#101](https://github.com/ipfs/go-graphsync/pull/101)) + - Release/0.2.0 ([ipfs/go-graphsync#99](https://github.com/ipfs/go-graphsync/pull/99)) + - fix(metadata): fix cbor-gen (#98) ([ipfs/go-graphsync#98](https://github.com/ipfs/go-graphsync/pull/98)) + - fix(selectorvalidator): memory optimization (#97) ([ipfs/go-graphsync#97](https://github.com/ipfs/go-graphsync/pull/97)) + - Update go-ipld-prime@v0.5.0 (#92) ([ipfs/go-graphsync#92](https://github.com/ipfs/go-graphsync/pull/92)) + - refactor(metadata): use cbor-gen encoding (#96) ([ipfs/go-graphsync#96](https://github.com/ipfs/go-graphsync/pull/96)) + - Release/v0.1.2 ([ipfs/go-graphsync#95](https://github.com/ipfs/go-graphsync/pull/95)) + - Return Request context cancelled error (#93) ([ipfs/go-graphsync#93](https://github.com/ipfs/go-graphsync/pull/93)) + - feat(benchmarks): add p2p stress test (#91) ([ipfs/go-graphsync#91](https://github.com/ipfs/go-graphsync/pull/91)) + - Benchmark framework + First memory fixes (#89) ([ipfs/go-graphsync#89](https://github.com/ipfs/go-graphsync/pull/89)) + - docs(CHANGELOG): update for v0.1.1 ([ipfs/go-graphsync#85](https://github.com/ipfs/go-graphsync/pull/85)) +- github.com/ipfs/go-ipfs-cmds (v0.4.0 -> v0.6.0): + - Added DelimitedStringsOption for enabling delimited strings on the CLI ([ipfs/go-ipfs-cmds#204](https://github.com/ipfs/go-ipfs-cmds/pull/204)) + - feat: support strings option over HTTP API ([ipfs/go-ipfs-cmds#203](https://github.com/ipfs/go-ipfs-cmds/pull/203)) +- github.com/ipfs/go-ipfs-config (v0.9.0 -> v0.12.0): + - add support for pinning mfs (#116) ([ipfs/go-ipfs-config#116](https://github.com/ipfs/go-ipfs-config/pull/116)) + - add remote pinning services config ([ipfs/go-ipfs-config#113](https://github.com/ipfs/go-ipfs-config/pull/113)) + - Remove badger2 profile ([ipfs/go-ipfs-config#115](https://github.com/ipfs/go-ipfs-config/pull/115)) + - Add badger2 profile and config spec +- github.com/ipfs/go-ipfs-pinner (v0.0.4 -> v0.1.1): + - Avoid loading all pins into memory during migration (#5) ([ipfs/go-ipfs-pinner#5](https://github.com/ipfs/go-ipfs-pinner/pull/5)) + - Datastore based pinner (#4) ([ipfs/go-ipfs-pinner#4](https://github.com/ipfs/go-ipfs-pinner/pull/4)) +- github.com/ipfs/go-ipld-cbor (v0.0.4 -> v0.0.5): + - add the ability to leverage zero-copy on blockstores. (#75) ([ipfs/go-ipld-cbor#75](https://github.com/ipfs/go-ipld-cbor/pull/75)) + - ipldstore: Also wrap Put serialization errors ([ipfs/go-ipld-cbor#74](https://github.com/ipfs/go-ipld-cbor/pull/74)) + - add helper constructor for inmem cbor store + - docs: add comments describing methods & interfaces ([ipfs/go-ipld-cbor#71](https://github.com/ipfs/go-ipld-cbor/pull/71)) +- github.com/ipfs/go-path (v0.0.8 -> v0.0.9): + - fix: improved error message on broken CIDv0 ([ipfs/go-path#33](https://github.com/ipfs/go-path/pull/33)) +- github.com/ipfs/go-pinning-service-http-client (null -> v0.1.0): + - feat: LsBatchSync to fetch single batch of results ([ipfs/go-pinning-service-http-client#6](https://github.com/ipfs/go-pinning-service-http-client/pull/6)) + - Initial Implementation ([ipfs/go-pinning-service-http-client#1](https://github.com/ipfs/go-pinning-service-http-client/pull/1)) +- github.com/ipld/go-car (v0.1.1-0.20200429200904-c222d793c339 -> v0.1.1-0.20201015032735-ff6ccdc46acc): + - Update ipld libs ([ipld/go-car#35](https://github.com/ipld/go-car/pull/35)) +- github.com/ipld/go-ipld-prime (v0.0.2-0.20200428162820-8b59dc292b8e -> v0.5.1-0.20201021195245-109253e8a018): + - Merge branch 'codec-hardening' + - Add fluent.MustReflect convenience method. + - codegen: make error info available when tuples process data that is too long. ([ipld/go-ipld-prime#99](https://github.com/ipld/go-ipld-prime/pull/99)) + - Merge branch 'codegen-typofixes' + - Implement resource budgets in dagcbor parsing. ([ipld/go-ipld-prime#85](https://github.com/ipld/go-ipld-prime/pull/85)) + - Codegen for links should emit the methods to conform to the schema.TypedLinkNode interface where applicable. ([ipld/go-ipld-prime#91](https://github.com/ipld/go-ipld-prime/pull/91)) + - Introduce fluent.Reflect convenience functions. ([ipld/go-ipld-prime#81](https://github.com/ipld/go-ipld-prime/pull/81)) + - schema/gen/go: make all top-level tests parallel + - all: don't use buffers where readers suffice + - fix typo in documentation + - schema-schema codegen demo now includes unmarshal exercise ([ipld/go-ipld-prime#76](https://github.com/ipld/go-ipld-prime/pull/76)) + - Update tests for unions; several fixes ([ipld/go-ipld-prime#75](https://github.com/ipld/go-ipld-prime/pull/75)) + - New testcase system for exercising typed nodes; Revamp struct tests to use it. ([ipld/go-ipld-prime#66](https://github.com/ipld/go-ipld-prime/pull/66)) + - small docs fixes on an internal component. + - Fix formatting in README. + - fix(cidlink): check for byte buffer ([ipld/go-ipld-prime#70](https://github.com/ipld/go-ipld-prime/pull/70)) + - linking/cid: check a previously unused error ([ipld/go-ipld-prime#68](https://github.com/ipld/go-ipld-prime/pull/68)) + - all: make 'go test ./...' pass on Go 1.15 ([ipld/go-ipld-prime#67](https://github.com/ipld/go-ipld-prime/pull/67)) + - Merge branch 'kinded-union-gen' + - Add traversal.Get function ([ipld/go-ipld-prime#65](https://github.com/ipld/go-ipld-prime/pull/65)) + - Kinded union gen ([ipld/go-ipld-prime#64](https://github.com/ipld/go-ipld-prime/pull/64)) + - Struct tuple representation codegen ([ipld/go-ipld-prime#63](https://github.com/ipld/go-ipld-prime/pull/63)) + - Merge branch 'moar-codegen' + - Self-hosting gen of the schema-schema. ([ipld/go-ipld-prime#62](https://github.com/ipld/go-ipld-prime/pull/62)) + - Codegen: approaching self-host ([ipld/go-ipld-prime#61](https://github.com/ipld/go-ipld-prime/pull/61)) + - Codegen of unions, and their keyed representations ([ipld/go-ipld-prime#60](https://github.com/ipld/go-ipld-prime/pull/60)) + - mark v0.5 + - API updates for v0.5: the renamening ([ipld/go-ipld-prime#59](https://github.com/ipld/go-ipld-prime/pull/59)) + - mark v0.4 + - changelog: note the codegen work. + - Codegen update -- Assemblers, and many new representations ([ipld/go-ipld-prime#52](https://github.com/ipld/go-ipld-prime/pull/52)) + - Merge branch 'json-tables-codec' + - Merge branch 'docs-updates' + - Introduce changelog! + - Add examples of creating and loading links. +- github.com/ipld/go-ipld-prime-proto (v0.0.0-20200428191222-c1ffdadc01e1 -> v0.1.0): + - Update go-ipld-prime ([ipld/go-ipld-prime-proto#6](https://github.com/ipld/go-ipld-prime-proto/pull/6)) + - feat(coding use -1 instead of 0): + - Update ipld prime, use proper code-gen ([ipld/go-ipld-prime-proto#5](https://github.com/ipld/go-ipld-prime-proto/pull/5)) + - Updates to dependencies ([ipld/go-ipld-prime-proto#4](https://github.com/ipld/go-ipld-prime-proto/pull/4)) + - Check for byte buffer on decode ([ipld/go-ipld-prime-proto#3](https://github.com/ipld/go-ipld-prime-proto/pull/3)) +- github.com/libp2p/go-libp2p (v0.11.0 -> v0.13.0): + - use a context when opening streams ([libp2p/go-libp2p#1033](https://github.com/libp2p/go-libp2p/pull/1033)) + - fix: obey new stream timeout ([libp2p/go-libp2p#1029](https://github.com/libp2p/go-libp2p/pull/1029)) + - feat: update to go-libp2p-core 0.7.0 interface changes ([libp2p/go-libp2p#1001](https://github.com/libp2p/go-libp2p/pull/1001)) + - Basic Connection Gater Implementation ([libp2p/go-libp2p#1005](https://github.com/libp2p/go-libp2p/pull/1005)) + - Fixed bug for inbound connections gated by the deprecated filter option (#1004) ([libp2p/go-libp2p#1004](https://github.com/libp2p/go-libp2p/pull/1004)) +- github.com/libp2p/go-libp2p-autonat (v0.3.2 -> v0.4.0): + - feat: update to go-libp2p-core 0.7.0 ([libp2p/go-libp2p-autonat#97](https://github.com/libp2p/go-libp2p-autonat/pull/97)) +- github.com/libp2p/go-libp2p-circuit (v0.3.1 -> v0.4.0): + - feat: update to go-libp2p-core 0.7.0 ([libp2p/go-libp2p-circuit#123](https://github.com/libp2p/go-libp2p-circuit/pull/123)) +- github.com/libp2p/go-libp2p-core (v0.6.1 -> v0.8.0): + - add a context to OpenStream and NewStream (#172) ([libp2p/go-libp2p-core#172](https://github.com/libp2p/go-libp2p-core/pull/172)) + - sec/insecure/insecure.go: Fix typo (#167) ([libp2p/go-libp2p-core#167](https://github.com/libp2p/go-libp2p-core/pull/167)) + - add CloseRead/CloseWrite on streams (#166) ([libp2p/go-libp2p-core#166](https://github.com/libp2p/go-libp2p-core/pull/166)) + - Fix typo in docs (#163) ([libp2p/go-libp2p-core#163](https://github.com/libp2p/go-libp2p-core/pull/163)) +- github.com/libp2p/go-libp2p-gostream (v0.2.1 -> v0.3.0): + - feat: use go-libp2p-core 0.7.0 stream interfaces ([libp2p/go-libp2p-gostream#60](https://github.com/libp2p/go-libp2p-gostream/pull/60)) +- github.com/libp2p/go-libp2p-http (v0.1.5 -> v0.2.0): + - Fix var name in README ([libp2p/go-libp2p-http#63](https://github.com/libp2p/go-libp2p-http/pull/63)) + - Fix var name in doc ([libp2p/go-libp2p-http#62](https://github.com/libp2p/go-libp2p-http/pull/62)) +- github.com/libp2p/go-libp2p-kad-dht (v0.9.0 -> v0.11.1): + - Fix constructor ordering ([libp2p/go-libp2p-kad-dht#698](https://github.com/libp2p/go-libp2p-kad-dht/pull/698)) + - feat: update to go-libp2p-core 0.7.0 ([libp2p/go-libp2p-kad-dht#693](https://github.com/libp2p/go-libp2p-kad-dht/pull/693)) + - Run fixLowPeers on startup ([libp2p/go-libp2p-kad-dht#694](https://github.com/libp2p/go-libp2p-kad-dht/pull/694)) + - feat: add advanced V1ProtocolOverride option to be used by legacy networks + - feat: remove dht v2 as it's not actually in use and could be confusing +- github.com/libp2p/go-libp2p-mplex (v0.2.4 -> v0.4.1): + - update go-mplex, use the context passed to OpenStream ([libp2p/go-libp2p-mplex#23](https://github.com/libp2p/go-libp2p-mplex/pull/23)) + - change OpenStream to accept a context ([libp2p/go-libp2p-mplex#21](https://github.com/libp2p/go-libp2p-mplex/pull/21)) + - feat: update stream interfaces ([libp2p/go-libp2p-mplex#20](https://github.com/libp2p/go-libp2p-mplex/pull/20)) +- github.com/libp2p/go-libp2p-noise (v0.1.1 -> v0.1.2): + - optimize: reduce syscalls using a buffered reader. +- github.com/libp2p/go-libp2p-pubsub (v0.3.5 -> v0.4.1): + - defer stream removal instead of doing it inline. + - add test for inbound stream deduplication + - deduplicate inbound streams + - populate receivedFrom field in delivery trace + - add receivedFrom field in delivery trace + - fix: reduce log spam (#394) ([libp2p/go-libp2p-pubsub#394](https://github.com/libp2p/go-libp2p-pubsub/pull/394)) + - fix: treat peers already connected to the host before pubsub is initialized as valid potential pubsub peers + - test: add test for if nodes are connected before pubsub is started + - feat: update to go-libp2p-core 0.7.0 + - Add go-libp2p example in README.md (#392) ([libp2p/go-libp2p-pubsub#392](https://github.com/libp2p/go-libp2p-pubsub/pull/392)) + - subscription filters + - remove multi-topic message support + - satisfy race detector + - clean up + - copy string topic + - add test for score adjustment from topis params reset + - prettify things + - add test for topic score parameter reset method + - add test for topic score parameter reset + - add api for dynamically setting and resetting topic score parameters + - add support for priority topic delivery weights + - tweak duplicate/reject weights + - decay global counters after 2 min + - decouple global coutner decay from source counter decay + - add warning for failure to parse IP out of remote multiaddr + - more docs + - configure the peer gater using a parameter object, docs and stuff + - disable codecov annotations, makes things unreadable + - further tweak gate threshold weights + - fix test races + - use IPs for peer gater stat tracking + - mix total accounting components with different weights + - count all rejections by default + - fix non-determinism in test + - tweak probability threshold + - also account for duplicates in gating decisions + - test throttle code path in gossip tracer + - add test for peer gater + - more efficient promise processing on throttling + - trace throttle peers to avoid breaking promises unfairly + - better log messages around gating + - implement peer gater + - peer gater scaffolding + - rich router acceptance semantics + - reduce log verbosity; debug mostly +- github.com/libp2p/go-libp2p-pubsub-router (v0.3.2 -> v0.4.0): + - feat: use new stream interfaces from go-libp2p-core 0.7.0 ([libp2p/go-libp2p-pubsub-router#81](https://github.com/libp2p/go-libp2p-pubsub-router/pull/81)) +- github.com/libp2p/go-libp2p-quic-transport (v0.8.0 -> v0.10.0): + - change OpenStream to accept a context ([libp2p/go-libp2p-quic-transport#189](https://github.com/libp2p/go-libp2p-quic-transport/pull/189)) + - update quic-go to v0.19.1 ([libp2p/go-libp2p-quic-transport#182](https://github.com/libp2p/go-libp2p-quic-transport/pull/182)) + - pass a conn that can be type asserted to a net.UDPConn to quic-go ([libp2p/go-libp2p-quic-transport#180](https://github.com/libp2p/go-libp2p-quic-transport/pull/180)) + - add more integration tests ([libp2p/go-libp2p-quic-transport#181](https://github.com/libp2p/go-libp2p-quic-transport/pull/181)) + - always close the connection in the cmd client ([libp2p/go-libp2p-quic-transport#175](https://github.com/libp2p/go-libp2p-quic-transport/pull/175)) + - use GitHub Actions to test interopability of releases ([libp2p/go-libp2p-quic-transport#173](https://github.com/libp2p/go-libp2p-quic-transport/pull/173)) + - Implement CloseRead/CloseWrite ([libp2p/go-libp2p-quic-transport#174](https://github.com/libp2p/go-libp2p-quic-transport/pull/174)) + - enable quic-go metrics collection ([libp2p/go-libp2p-quic-transport#172](https://github.com/libp2p/go-libp2p-quic-transport/pull/172)) +- github.com/libp2p/go-libp2p-swarm (v0.2.8 -> v0.4.0): + - use a context for OpenStream and NewStream ([libp2p/go-libp2p-swarm#232](https://github.com/libp2p/go-libp2p-swarm/pull/232)) + - fix: handle case where swarm closes before stream ([libp2p/go-libp2p-swarm#229](https://github.com/libp2p/go-libp2p-swarm/pull/229)) + - feat: update to latest go-libp2p-core interfaces ([libp2p/go-libp2p-swarm#228](https://github.com/libp2p/go-libp2p-swarm/pull/228)) +- github.com/libp2p/go-libp2p-testing (v0.2.0 -> v0.4.0): + - pass contexts to OpenStream in tests ([libp2p/go-libp2p-testing#31](https://github.com/libp2p/go-libp2p-testing/pull/31)) + - chore: Adding LICENSE. ([libp2p/go-libp2p-testing#30](https://github.com/libp2p/go-libp2p-testing/pull/30)) + - feat: update to go-libp2p-core 0.7.0 ([libp2p/go-libp2p-testing#29](https://github.com/libp2p/go-libp2p-testing/pull/29)) +- github.com/libp2p/go-libp2p-transport-upgrader (v0.3.0 -> v0.4.0): + - pass contexts to OpenStream in tests ([libp2p/go-libp2p-transport-upgrader#70](https://github.com/libp2p/go-libp2p-transport-upgrader/pull/70)) + - fix int to string conversion in tests, update Go version on CI ([libp2p/go-libp2p-transport-upgrader#69](https://github.com/libp2p/go-libp2p-transport-upgrader/pull/69)) +- github.com/libp2p/go-libp2p-yamux (v0.2.8 -> v0.5.1): + - update go-yamux to v2.0.0, use context passed to OpenStream ([libp2p/go-libp2p-yamux#31](https://github.com/libp2p/go-libp2p-yamux/pull/31)) + - change OpenStream to accept a context ([libp2p/go-libp2p-yamux#29](https://github.com/libp2p/go-libp2p-yamux/pull/29)) + - feat: update to new stream interfaces ([libp2p/go-libp2p-yamux#27](https://github.com/libp2p/go-libp2p-yamux/pull/27)) +- github.com/libp2p/go-mplex (v0.1.2 -> v0.3.0): + - add a context to NewStream, remove the NewStreamTimeout ([libp2p/go-mplex#82](https://github.com/libp2p/go-mplex/pull/82)) + - Implement new CloseWrite/CloseRead interface ([libp2p/go-mplex#81](https://github.com/libp2p/go-mplex/pull/81)) + - Bump lodash from 4.17.15 to 4.17.19 in /interop/js ([libp2p/go-mplex#79](https://github.com/libp2p/go-mplex/pull/79)) + - upgrade deps + interoperable varints. (#80) ([libp2p/go-mplex#80](https://github.com/libp2p/go-mplex/pull/80)) + - write benchmarks (#77) ([libp2p/go-mplex#77](https://github.com/libp2p/go-mplex/pull/77)) +- github.com/libp2p/go-ws-transport (v0.3.1 -> v0.4.0): + - pass a context to OpenStream in tests ([libp2p/go-ws-transport#98](https://github.com/libp2p/go-ws-transport/pull/98)) + - Dependency: Remove deprecated multiaddr-net ([libp2p/go-ws-transport#97](https://github.com/libp2p/go-ws-transport/pull/97)) + - Update for go 1.14 Wasm changes ([libp2p/go-ws-transport#96](https://github.com/libp2p/go-ws-transport/pull/96)) +- github.com/libp2p/go-yamux (v1.3.7 -> v1.4.1): + - feat: improve ping accuracy ([libp2p/go-yamux#35](https://github.com/libp2p/go-yamux/pull/35)) + - implement CloseRead/CloseWrite ([libp2p/go-yamux#5](https://github.com/libp2p/go-yamux/pull/5)) + - fix space accounting in the receive buffer ([libp2p/go-yamux#33](https://github.com/libp2p/go-yamux/pull/33)) + - Limit pings ([libp2p/go-yamux#32](https://github.com/libp2p/go-yamux/pull/32)) + - fix: simplify inflight fix ([libp2p/go-yamux#31](https://github.com/libp2p/go-yamux/pull/31)) + - Clearing inflight along with streams to avoid memory leak ([libp2p/go-yamux#30](https://github.com/libp2p/go-yamux/pull/30)) +- github.com/lucas-clemente/quic-go (v0.18.0 -> v0.19.3): + - create a v0.19.x release + - improve the warning about the UDP receive buffer size ([lucas-clemente/quic-go#2923](https://github.com/lucas-clemente/quic-go/pull/2923)) + - immediately remove reset tokens when retiring a connection ID ([lucas-clemente/quic-go#2897](https://github.com/lucas-clemente/quic-go/pull/2897)) + - add common temporary file patterns to .gitignore ([lucas-clemente/quic-go#2917](https://github.com/lucas-clemente/quic-go/pull/2917)) + - disable key updates when using HTTP/3 to avoid breaking Chrome 87 ([lucas-clemente/quic-go#2906](https://github.com/lucas-clemente/quic-go/pull/2906)) + - fix decoding of packet numbers in different packet number spaces ([lucas-clemente/quic-go#2903](https://github.com/lucas-clemente/quic-go/pull/2903)) + - log sent packet before logging its congestion / loss recovery effects ([lucas-clemente/quic-go#2912](https://github.com/lucas-clemente/quic-go/pull/2912)) + - fix a crash in the http3.Server when GetConfigForClient returns nil ([lucas-clemente/quic-go#2925](https://github.com/lucas-clemente/quic-go/pull/2925)) + - set the UDP receive buffer size on Windows ([lucas-clemente/quic-go#2896](https://github.com/lucas-clemente/quic-go/pull/2896)) + - remove superfluous sleep in packet handler map test ([lucas-clemente/quic-go#2894](https://github.com/lucas-clemente/quic-go/pull/2894)) + - fix setting of http.Handler in the example server ([lucas-clemente/quic-go#2900](https://github.com/lucas-clemente/quic-go/pull/2900)) + - remove stray print statement + - remove unnecessary mutex locking in the stream flow controller ([lucas-clemente/quic-go#2869](https://github.com/lucas-clemente/quic-go/pull/2869)) + - only use syscalls on platforms that we're actually testing ([lucas-clemente/quic-go#2886](https://github.com/lucas-clemente/quic-go/pull/2886)) + - only write headers with a length that fits into 2 bytes in fuzz test ([lucas-clemente/quic-go#2884](https://github.com/lucas-clemente/quic-go/pull/2884)) + - fix packing of 1-RTT probe packets ([lucas-clemente/quic-go#2882](https://github.com/lucas-clemente/quic-go/pull/2882)) + - use PADDING frames to pad packets ([lucas-clemente/quic-go#2876](https://github.com/lucas-clemente/quic-go/pull/2876)) + - fix race condition when accepting streams ([lucas-clemente/quic-go#2874](https://github.com/lucas-clemente/quic-go/pull/2874)) + - only trace dropped 0-RTT packets when a tracer is set ([lucas-clemente/quic-go#2871](https://github.com/lucas-clemente/quic-go/pull/2871)) + - use consistent version numbers in client test ([lucas-clemente/quic-go#2870](https://github.com/lucas-clemente/quic-go/pull/2870)) + - replace the RWMutex with a Mutex in the flow controller ([lucas-clemente/quic-go#2865](https://github.com/lucas-clemente/quic-go/pull/2865)) + - replace the RWMutex with a Mutex in the packet handler map ([lucas-clemente/quic-go#2864](https://github.com/lucas-clemente/quic-go/pull/2864)) + - wait until the handshake is complete before updating the connection ID ([lucas-clemente/quic-go#2856](https://github.com/lucas-clemente/quic-go/pull/2856)) + - only check the SCID for Initial packets ([lucas-clemente/quic-go#2857](https://github.com/lucas-clemente/quic-go/pull/2857)) + - add the NO_VIABLE_PATH error ([lucas-clemente/quic-go#2861](https://github.com/lucas-clemente/quic-go/pull/2861)) + - implement qlogging of the preferred address in the transport parameters ([lucas-clemente/quic-go#2853](https://github.com/lucas-clemente/quic-go/pull/2853)) + - explicitly set the supported versions in the HTTP/3 server test ([lucas-clemente/quic-go#2854](https://github.com/lucas-clemente/quic-go/pull/2854)) + - allow an amplification factor of 3.x ([lucas-clemente/quic-go#2862](https://github.com/lucas-clemente/quic-go/pull/2862)) + - only allow the HTTP/3 client to dial with a single QUIC version ([lucas-clemente/quic-go#2848](https://github.com/lucas-clemente/quic-go/pull/2848)) + - send STREAMS_BLOCKED frame when MAX_STREAMS frame allows too few streams ([lucas-clemente/quic-go#2828](https://github.com/lucas-clemente/quic-go/pull/2828)) + - set the ALPN based on the QUIC version in the HTTP3 server ([lucas-clemente/quic-go#2847](https://github.com/lucas-clemente/quic-go/pull/2847)) + - pad datagrams containing ack-eliciting Initial packets sent by the server ([lucas-clemente/quic-go#2841](https://github.com/lucas-clemente/quic-go/pull/2841)) + - fix OpenStreamSync busy looping ([lucas-clemente/quic-go#2827](https://github.com/lucas-clemente/quic-go/pull/2827)) + - fix deadlock when closing the server and the connection at the same time ([lucas-clemente/quic-go#2849](https://github.com/lucas-clemente/quic-go/pull/2849)) + - run gofumpt, enable the gofumpt linter ([lucas-clemente/quic-go#2839](https://github.com/lucas-clemente/quic-go/pull/2839)) + - prepare for draft-32 ([lucas-clemente/quic-go#2831](https://github.com/lucas-clemente/quic-go/pull/2831)) + - update the invalid packet limit for AES ([lucas-clemente/quic-go#2825](https://github.com/lucas-clemente/quic-go/pull/2825)) + - increase UDP receive buffer size ([lucas-clemente/quic-go#2791](https://github.com/lucas-clemente/quic-go/pull/2791)) + - listen on both IPv4 and IPv6 in the interop runner server ([lucas-clemente/quic-go#2822](https://github.com/lucas-clemente/quic-go/pull/2822)) + - only send Version Negotiation packets for packets larger than 1200 bytes ([lucas-clemente/quic-go#2820](https://github.com/lucas-clemente/quic-go/pull/2820)) + - don't send a version negotiation packet in response to a version negotiation packet ([lucas-clemente/quic-go#2818](https://github.com/lucas-clemente/quic-go/pull/2818)) + - client: Add DialEarlyContext and DialAddrEarlyContext API ([lucas-clemente/quic-go#2814](https://github.com/lucas-clemente/quic-go/pull/2814)) + - qlog the key phase bit ([lucas-clemente/quic-go#2817](https://github.com/lucas-clemente/quic-go/pull/2817)) + - only include quic-trace when the quictrace build flag is set ([lucas-clemente/quic-go#2799](https://github.com/lucas-clemente/quic-go/pull/2799)) + - fix error handling when receiving post handshake messages ([lucas-clemente/quic-go#2807](https://github.com/lucas-clemente/quic-go/pull/2807)) + - add support for the ChaCha20 test on the server side ([lucas-clemente/quic-go#2816](https://github.com/lucas-clemente/quic-go/pull/2816)) + - allow the first key update immediately after handshake confirmation ([lucas-clemente/quic-go#2811](https://github.com/lucas-clemente/quic-go/pull/2811)) + - ignore temporary errors when reading from the packet conn ([lucas-clemente/quic-go#2806](https://github.com/lucas-clemente/quic-go/pull/2806)) + - fix linting error on OSX ([lucas-clemente/quic-go#2813](https://github.com/lucas-clemente/quic-go/pull/2813)) + - add the exhaustive linter, replace panics by return values in logging stringers ([lucas-clemente/quic-go#2729](https://github.com/lucas-clemente/quic-go/pull/2729)) + - include the error code in the string for CRYPTO_ERRORs ([lucas-clemente/quic-go#2805](https://github.com/lucas-clemente/quic-go/pull/2805)) + - fail the handshake if the quic_transport_parameter extension is missing ([lucas-clemente/quic-go#2804](https://github.com/lucas-clemente/quic-go/pull/2804)) + - fix logging of received Retry packets ([lucas-clemente/quic-go#2803](https://github.com/lucas-clemente/quic-go/pull/2803)) + - fix deadlock in crypto setup when it is closed while handling a message ([lucas-clemente/quic-go#2802](https://github.com/lucas-clemente/quic-go/pull/2802)) + - make the key update integration test more rigorous ([lucas-clemente/quic-go#2760](https://github.com/lucas-clemente/quic-go/pull/2760)) + - add support for the new keyupdate interop runner test case ([lucas-clemente/quic-go#2782](https://github.com/lucas-clemente/quic-go/pull/2782)) + - remove unneeded mutex in the client ([lucas-clemente/quic-go#2798](https://github.com/lucas-clemente/quic-go/pull/2798)) + - correctly handle key updates within the 3 PTO period ([lucas-clemente/quic-go#2787](https://github.com/lucas-clemente/quic-go/pull/2787)) + - introduce an ECNCapablePacketConn interface to determine ECN support ([lucas-clemente/quic-go#2788](https://github.com/lucas-clemente/quic-go/pull/2788)) + - use certificates from /certs directory for the server ([lucas-clemente/quic-go#2794](https://github.com/lucas-clemente/quic-go/pull/2794)) + - remove support for the ECN test case ([lucas-clemente/quic-go#2793](https://github.com/lucas-clemente/quic-go/pull/2793)) + - check that the peer updated its keys when acknowledging a key update ([lucas-clemente/quic-go#2781](https://github.com/lucas-clemente/quic-go/pull/2781)) + - fix flaky packet number skipping test ([lucas-clemente/quic-go#2786](https://github.com/lucas-clemente/quic-go/pull/2786)) + - read ECN bits and send ECN counters in ACK frames ([lucas-clemente/quic-go#2741](https://github.com/lucas-clemente/quic-go/pull/2741)) + - implement the limit of unsuccessful decryptions for the AEADs ([lucas-clemente/quic-go#2771](https://github.com/lucas-clemente/quic-go/pull/2771)) + - use the KEY_UPDATE_ERROR ([lucas-clemente/quic-go#2770](https://github.com/lucas-clemente/quic-go/pull/2770)) + - fix dropping of key phase 0 ([lucas-clemente/quic-go#2769](https://github.com/lucas-clemente/quic-go/pull/2769)) + - reduce the handshake timeout to two minutes in the handshake drop tests ([lucas-clemente/quic-go#2768](https://github.com/lucas-clemente/quic-go/pull/2768)) + - fix handling of multiple handshake messages in the case of errors ([lucas-clemente/quic-go#2777](https://github.com/lucas-clemente/quic-go/pull/2777)) + - enable more linters, update golangci-lint to v1.31 ([lucas-clemente/quic-go#2775](https://github.com/lucas-clemente/quic-go/pull/2775)) + - increase the threshold for the receive stream deadline test ([lucas-clemente/quic-go#2774](https://github.com/lucas-clemente/quic-go/pull/2774)) + - add an assertion that bytes_in_flight never becomes negative ([lucas-clemente/quic-go#2779](https://github.com/lucas-clemente/quic-go/pull/2779)) + - fix race condition in handshake fuzz code ([lucas-clemente/quic-go#2778](https://github.com/lucas-clemente/quic-go/pull/2778)) + - use more tls.Config options in the handshake fuzzer ([lucas-clemente/quic-go#2746](https://github.com/lucas-clemente/quic-go/pull/2746)) + - run two handshakes in the handshake fuzzer ([lucas-clemente/quic-go#2743](https://github.com/lucas-clemente/quic-go/pull/2743)) + - send post-handshake message in the handshake fuzzer ([lucas-clemente/quic-go#2742](https://github.com/lucas-clemente/quic-go/pull/2742)) + - skip a packet number when sending a 1-RTT PTO packet ([lucas-clemente/quic-go#2754](https://github.com/lucas-clemente/quic-go/pull/2754)) + - save dummy packets in the packet history when skipping packet numbers ([lucas-clemente/quic-go#2753](https://github.com/lucas-clemente/quic-go/pull/2753)) + - delete unacknowledged packets from the packet history after 3 PTOs ([lucas-clemente/quic-go#2750](https://github.com/lucas-clemente/quic-go/pull/2750)) + - add support for the HTTP CONNECT method (#2761) ([lucas-clemente/quic-go#2761](https://github.com/lucas-clemente/quic-go/pull/2761)) + - don't drop keys for key phase N before receiving a N+1-protected packet ([lucas-clemente/quic-go#2762](https://github.com/lucas-clemente/quic-go/pull/2762)) + - close session on errors unpacking errors other than decryption errors ([lucas-clemente/quic-go#2756](https://github.com/lucas-clemente/quic-go/pull/2756)) + - log when an old 1-RTT key is retired ([lucas-clemente/quic-go#2765](https://github.com/lucas-clemente/quic-go/pull/2765)) + - only return an invalid first key phase error for decryptable packets ([lucas-clemente/quic-go#2757](https://github.com/lucas-clemente/quic-go/pull/2757)) + - fix logging of locally initiated key updates ([lucas-clemente/quic-go#2764](https://github.com/lucas-clemente/quic-go/pull/2764)) + - test that both endpoints time out in the timeout integration test ([lucas-clemente/quic-go#2744](https://github.com/lucas-clemente/quic-go/pull/2744)) + - refactor RTT measurements to simplify the sentPacketHistory ([lucas-clemente/quic-go#2747](https://github.com/lucas-clemente/quic-go/pull/2747)) + - fix dropping of 0-RTT packets ([lucas-clemente/quic-go#2752](https://github.com/lucas-clemente/quic-go/pull/2752)) + - always qlog the generation of 1-RTT key updates ([lucas-clemente/quic-go#2763](https://github.com/lucas-clemente/quic-go/pull/2763)) + - move the PacketHeader struct from logging to qlog package ([lucas-clemente/quic-go#2766](https://github.com/lucas-clemente/quic-go/pull/2766)) + - use a uint8 for the EncryptionLevel ([lucas-clemente/quic-go#2751](https://github.com/lucas-clemente/quic-go/pull/2751)) + - make sure to only pass handshake messages that keys are available for ([lucas-clemente/quic-go#2739](https://github.com/lucas-clemente/quic-go/pull/2739)) + - only close the handshake fuzz runner once ([lucas-clemente/quic-go#2740](https://github.com/lucas-clemente/quic-go/pull/2740)) + - generate a self-signed certificate for the handshake fuzzer ([lucas-clemente/quic-go#2738](https://github.com/lucas-clemente/quic-go/pull/2738)) + - use the os.ErrDeadlineExceeded for stream deadline errors on Go 1.15 ([lucas-clemente/quic-go#2734](https://github.com/lucas-clemente/quic-go/pull/2734)) + - use GitHub Actions to run unit tests ([lucas-clemente/quic-go#2732](https://github.com/lucas-clemente/quic-go/pull/2732)) + - add a basic fuzzer for the handshake ([lucas-clemente/quic-go#2733](https://github.com/lucas-clemente/quic-go/pull/2733)) + - export seed corpus files using the SHA1 of the content as the filename ([lucas-clemente/quic-go#2731](https://github.com/lucas-clemente/quic-go/pull/2731)) + - add a fuzz target for the token generator ([lucas-clemente/quic-go#2730](https://github.com/lucas-clemente/quic-go/pull/2730)) + - fix typo in error message in sent packet handler + - fix missing OnLost callback for frames sent in 0-RTT packets ([lucas-clemente/quic-go#2728](https://github.com/lucas-clemente/quic-go/pull/2728)) + - fix overflow of the max_ack_delay when parsing transport parameters ([lucas-clemente/quic-go#2725](https://github.com/lucas-clemente/quic-go/pull/2725)) +- github.com/marten-seemann/qpack (v0.2.0 -> v0.2.1): + - run gofumpt, add a few more linters ([marten-seemann/qpack#21](https://github.com/marten-seemann/qpack/pull/21)) + - fix static table entry 80 ([marten-seemann/qpack#20](https://github.com/marten-seemann/qpack/pull/20)) +- github.com/marten-seemann/qtls-go1-15 (v0.1.0 -> v0.1.1): + - use a prefix for client session cache keys + - add callbacks to store and restore app data along a session state + - don't use TLS 1.3 compatibility mode when using alternative record layer + - delete the session ticket after attempting 0-RTT + - reject 0-RTT when a different ALPN is chosen + - encode the ALPN into the session ticket + - add a field to the ConnectionState to tell if 0-RTT was used + - add a callback to tell the client about rejection of 0-RTT + - don't offer 0-RTT after a HelloRetryRequest + - add Accept0RTT to Config callback to decide if 0-RTT should be accepted + - add the option to encode application data into the session ticket + - export the 0-RTT write key + - abuse the nonce field of ClientSessionState to save max_early_data_size + - export the 0-RTT read key + - close connection if client attempts 0-RTT, but ticket didn't allow it + - encode the max early data size into the session ticket + - implement parsing of the early_data extension in the EncryptedExtensions + - add a tls.Config.MaxEarlyData option to enable 0-RTT + - accept TLS 1.3 cipher suites in Config.CipherSuites + - introduce a function on the connection to generate a session ticket + - add a config option to enforce selection of an application protocol + - export Conn.HandlePostHandshakeMessage + - export Alert + - reject Configs that set MaxVersion < 1.3 when using a record layer + - enforce TLS 1.3 when using an alternative record layer +- github.com/multiformats/go-multistream (v0.1.2 -> v0.2.0): + - improve negotiation flushing ([multiformats/go-multistream#52](https://github.com/multiformats/go-multistream/pull/52)) +- github.com/whyrusleeping/cbor-gen (v0.0.0-20200402171437-3d27c146c105 -> v0.0.0-20200710004633-5379fc63235d): + - correctly map typegen to cbg in all cases ([whyrusleeping/cbor-gen#26](https://github.com/whyrusleeping/cbor-gen/pull/26)) + - fix: clear struct state on unmarshal ([whyrusleeping/cbor-gen#22](https://github.com/whyrusleeping/cbor-gen/pull/22)) + - deferred: restrict max length ([whyrusleeping/cbor-gen#25](https://github.com/whyrusleeping/cbor-gen/pull/25)) + - reduce number of allocations in ScanForLinks ([whyrusleeping/cbor-gen#24](https://github.com/whyrusleeping/cbor-gen/pull/24)) + - attempt to allocate less by using shared buffers ([whyrusleeping/cbor-gen#18](https://github.com/whyrusleeping/cbor-gen/pull/18)) + - add benchmark + - use new cid methods for less allocs ([whyrusleeping/cbor-gen#17](https://github.com/whyrusleeping/cbor-gen/pull/17)) + - properly handle roundtripping Deferred with 'null' value ([whyrusleeping/cbor-gen#16](https://github.com/whyrusleeping/cbor-gen/pull/16)) + - Support array types ([whyrusleeping/cbor-gen#15](https://github.com/whyrusleeping/cbor-gen/pull/15)) +- github.com/whyrusleeping/tar-utils (v0.0.0-20180509141711-8c6c8ba81d5c -> v0.0.0-20201201191210-20a61371de5b): + - more closely match default tar errors (GNU + BSD binaries) + +Contributors + +| Contributor | Commits | Lines ± | Files Changed | +|-------------|---------|---------|---------------| +| Eric Myhre | 180 | +26453/-11032 | 883 | +| Marten Seemann | 212 | +14876/-9352 | 794 | +| hannahhoward | 41 | +9195/-3113 | 186 | +| Alex Cruikshank | 5 | +3323/-1895 | 58 | +| Andrew Gillis | 3 | +3792/-581 | 21 | +| vyzo | 49 | +2675/-949 | 95 | +| Adin Schmahmann | 57 | +1473/-837 | 90 | +| Steven Allen | 43 | +1252/-780 | 99 | +| Petar Maymounkov | 3 | +1755/-113 | 17 | +| Marcin Rataj | 35 | +979/-210 | 61 | +| Paul Wolneykien | 2 | +670/-338 | 9 | +| Jeromy Johnson | 9 | +525/-221 | 21 | +| gammazero | 11 | +366/-101 | 26 | +| Hector Sanjuan | 7 | +312/-0 | 11 | +| Dirk McCormick | 4 | +190/-90 | 15 | +| Will Scott | 1 | +252/-0 | 1 | +| Oli Evans | 1 | +201/-0 | 1 | +| Tomasz Zdybał | 2 | +182/-3 | 6 | +| Daniel Martí | 6 | +104/-66 | 35 | +| Sam | 3 | +76/-59 | 5 | +| Łukasz Magiera | 2 | +92/-3 | 5 | +| whyrusleeping | 3 | +77/-15 | 3 | +| nisdas | 3 | +76/-15 | 4 | +| Raúl Kripalani | 3 | +59/-31 | 5 | +| Lucas Molas | 1 | +66/-3 | 2 | +| Alex Towle | 1 | +52/-8 | 2 | +| Dennis Trautwein | 1 | +58/-0 | 2 | +| Adrian Lanzafame | 2 | +49/-7 | 4 | +| klzgrad | 1 | +49/-5 | 2 | +| Fazlul Shahriar | 1 | +35/-14 | 17 | +| Yingrong Zhao | 1 | +45/-2 | 2 | +| Jakub Sztandera | 2 | +22/-13 | 2 | +| Chaitanya | 8 | +16/-16 | 8 | +| Aarsh Shah | 1 | +27/-1 | 3 | +| Rod Vagg | 1 | +23/-4 | 2 | +| M. Hawn | 4 | +11/-11 | 8 | +| Will | 1 | +12/-2 | 1 | +| frrist | 1 | +7/-0 | 1 | +| Rafael Ramalho | 2 | +5/-2 | 2 | +| dependabot[bot] | 1 | +3/-3 | 1 | +| Zaurbek Zhakupov | 1 | +3/-3 | 1 | +| Tom Worrall | 1 | +4/-2 | 1 | +| Jorropo | 2 | +5/-1 | 2 | +| Chaitanya Raju | 1 | +3/-3 | 2 | +| Egon Elbre | 1 | +0/-5 | 1 | +| incognitomode | 1 | +2/-2 | 1 | +| achingbrain | 1 | +2/-2 | 1 | +| Michael Burns | 1 | +2/-2 | 1 | +| David Florness | 2 | +2/-2 | 2 | +| RubenKelevra | 1 | +2/-1 | 1 | +| Andrew Nesbitt | 2 | +2/-1 | 2 | +| Tarun Bansal | 1 | +1/-1 | 1 | +| Max Inden | 1 | +1/-1 | 1 | +| K | 1 | +2/-0 | 1 | +| Jacob Heun | 1 | +1/-1 | 1 | +| Henrique Dias | 1 | +1/-1 | 1 | +| Bryan White | 1 | +1/-1 | 1 | +| Bryan Stenson | 1 | +1/-1 | 1 | + ## v0.7.0 2020-09-22 ### Highlights